diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.env.example b/.env.example old mode 100644 new mode 100755 diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 167fe3f9..8e54f252 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ /storage/*.key /storage/pail /vendor +/redis_data Homestead.json Homestead.yaml Thumbs.db diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/app/Console/Commands/RunAiJob.php b/app/Console/Commands/RunAiJob.php old mode 100644 new mode 100755 index f0518ca4..f2174b1f --- a/app/Console/Commands/RunAiJob.php +++ b/app/Console/Commands/RunAiJob.php @@ -28,47 +28,47 @@ class RunAiJob extends Command */ public function handle() { - $response = Http::withHeaders([ - 'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA2OWZlZGJiLTk2ZDctNGU4MC1iMDA0LWFmZDZjMmU4YmZkZiIsImxhc3RfcGFzc3dvcmRfY2hhbmdlIjoxNzUwNjYwODczLCJleHAiOjE3NTQ3NTcxMDR9.qAQF8XDOU8NRz5vSiFlQfnrj8dhGhJ5uvJqjblQWmr8', - 'Cookie' => 'x-ap=eu-central-1; acw_tc=0a03e56c17521661095906021e3cacb270c127c80eb3a20489a465ab4beae1', - ])->post('https://chat.qwen.ai/api/v2/chat/completions?chat_id=7ce2a60a-2b40-4ae8-8536-0cd346642de3', [ - 'stream' => false, - 'incremental_output' => true, - 'chat_id' => '7ce2a60a-2b40-4ae8-8536-0cd346642de3', - 'chat_mode' => 'normal', - 'model' => 'qwen3-235b-a22b', - 'messages' => [ - [ - 'role' => 'user', - 'content' => 'یه جمله انگیزشی بده که خاص، کوبنده و غیرکلیشه‌ای باشه. نه مثل بقیه.', - 'user_action' => 'chat', - 'files' => [], - 'timestamp' => 1752165316, - 'models' => ['qwen3-235b-a22b'], - 'chat_type' => 't2t', - 'feature_config' => [ - 'thinking_enabled' => false, - 'output_schema' => 'phase' - ], - 'extra' => [ - 'meta' => [ - 'subChatType' => 't2t' - ] - ], - 'sub_chat_type' => 't2t', - 'parent_id' => 'df0a0c91-53d5-4a04-b5da-b8ac53d6d821' - ] - ], - 'timestamp' => 1752165316 - ]); -// Get the response - $responseData = $response->json(); - $content = $responseData['data']['choices'][0]['message']['content']; - $ai = new ai(); // Or use your correct namespace - $ai->key = 'angizeh'; // Assuming you fixed 'kay' to 'key' in migration - $ai->prompt = 'فقط یک جمله کوتاه انگیزشی بگو'; - $ai->response = $content; - $ai->save(); +// $response = Http::withHeaders([ +// 'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA2OWZlZGJiLTk2ZDctNGU4MC1iMDA0LWFmZDZjMmU4YmZkZiIsImxhc3RfcGFzc3dvcmRfY2hhbmdlIjoxNzUwNjYwODczLCJleHAiOjE3NTQ3NTcxMDR9.qAQF8XDOU8NRz5vSiFlQfnrj8dhGhJ5uvJqjblQWmr8', +// 'Cookie' => 'x-ap=eu-central-1; acw_tc=0a03e56c17521661095906021e3cacb270c127c80eb3a20489a465ab4beae1', +// ])->post('https://chat.qwen.ai/api/v2/chat/completions?chat_id=7ce2a60a-2b40-4ae8-8536-0cd346642de3', [ +// 'stream' => false, +// 'incremental_output' => true, +// 'chat_id' => '7ce2a60a-2b40-4ae8-8536-0cd346642de3', +// 'chat_mode' => 'normal', +// 'model' => 'qwen3-235b-a22b', +// 'messages' => [ +// [ +// 'role' => 'user', +// 'content' => 'یه جمله انگیزشی بده که خاص، کوبنده و غیرکلیشه‌ای باشه. نه مثل بقیه.', +// 'user_action' => 'chat', +// 'files' => [], +// 'timestamp' => 1752165316, +// 'models' => ['qwen3-235b-a22b'], +// 'chat_type' => 't2t', +// 'feature_config' => [ +// 'thinking_enabled' => false, +// 'output_schema' => 'phase' +// ], +// 'extra' => [ +// 'meta' => [ +// 'subChatType' => 't2t' +// ] +// ], +// 'sub_chat_type' => 't2t', +// 'parent_id' => 'df0a0c91-53d5-4a04-b5da-b8ac53d6d821' +// ] +// ], +// 'timestamp' => 1752165316 +// ]); +//// Get the response +// $responseData = $response->json(); +// $content = $responseData['data']['choices'][0]['message']['content']; +// $ai = new ai(); // Or use your correct namespace +// $ai->key = 'angizeh'; // Assuming you fixed 'kay' to 'key' in migration +// $ai->prompt = 'فقط یک جمله کوتاه انگیزشی بگو'; +// $ai->response = $content; +// $ai->save(); $this->info('AI Job dispatched successfully!'); } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php old mode 100644 new mode 100755 diff --git a/app/Jobs/AiJob.php b/app/Jobs/AiJob.php old mode 100644 new mode 100755 diff --git a/app/Models/Attendance.php b/app/Models/Attendance.php index d82a4e1c..5c781e24 100644 --- a/app/Models/Attendance.php +++ b/app/Models/Attendance.php @@ -4,9 +4,12 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; +use Carbon\Carbon; class Attendance extends Model { + // protected $appends = ['full_time']; + protected $fillable = [ 'user_id', 'user_identity', @@ -21,6 +24,7 @@ class Attendance extends Model 'ip_address', 'entered_at', 'exited_at', + 'requested', ]; public function setEntryLocationAttribute($value) @@ -42,5 +46,39 @@ class Attendance extends Model { return $this->hasMany(AttendanceBreak::class); } + + public function duration($start,$end) + { + // dd($start,$end, $date); + $fakedate = '2020/02/20'; + $start = Carbon::parse($start)->format('Y/m/d') ? Carbon::parse($start) : Carbon::parse($start . $fakedate); + $end = Carbon::parse($end)->format('Y/m/d') ? Carbon::parse($end) : Carbon::parse($end . $fakedate); + + + $diffInSeconds = $start->diffInSeconds($end); // فاصله به ثانیه + $hours = floor($diffInSeconds / 3600); + $minutes = floor(($diffInSeconds % 3600) / 60); + $seconds = $diffInSeconds % 60; + + $duration = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds); + return $duration; + } +// public function attendanceBreak() +// { +// +// return $this->hasMany(AttendanceBreak::class, 'attendance_id', 'id') +// ->select('attendance_id', 'break_start', 'break_end', 'duration') +// ->orderBy('break_start', 'desc'); +// +// +// } + public function attendanceBreaks() + { + return $this->hasMany(AttendanceBreak::class, 'attendance_id', 'id') + ->orderBy('break_start', 'desc'); + } + + + public $timestamps = true; } diff --git a/app/Models/AttendanceBreak.php b/app/Models/AttendanceBreak.php old mode 100644 new mode 100755 index 7b262cee..fade64db --- a/app/Models/AttendanceBreak.php +++ b/app/Models/AttendanceBreak.php @@ -11,6 +11,7 @@ class AttendanceBreak extends Model 'attendance_id', 'break_start', 'break_end', + 'duration', ]; // رابطه به حضور diff --git a/app/Models/Tasks.php b/app/Models/Tasks.php new file mode 100644 index 00000000..c4d3617f --- /dev/null +++ b/app/Models/Tasks.php @@ -0,0 +1,55 @@ +belongsToMany(User::class, 'pivot_tasks', 'task_id', 'user_id'); + return $this->belongsToMany( + User::class, // مدل مقصد + 'pivot_tasks', // جدول واسط + 'task_id', // ستون جدول واسط که به جدول tasks اشاره می‌کنه + 'user_id', // ستون جدول واسط که به جدول users اشاره می‌کنه + 'task_id', // ستون جدول tasks که ستون واسط بهش اشاره می‌کنه (local key) + 'plain_id' // ستون جدول users که ستون واسط بهش اشاره می‌کنه (related key) + ); + } +} diff --git a/app/Models/User.php b/app/Models/User.php old mode 100644 new mode 100755 index 749c7b77..4742c995 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,24 +3,36 @@ namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; + +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Illuminate\Support\Facades\DB; +use Morilog\Jalali\Jalalian; + class User extends Authenticatable { /** @use HasFactory<\Database\Factories\UserFactory> */ use HasFactory, Notifiable; + /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ - 'name', 'email', + 'chatid', + 'name', + 'number', 'password', + 'user_name', + 'is_admin', + 'plain_id', + ]; /** @@ -28,10 +40,7 @@ class User extends Authenticatable * * @var list */ - protected $hidden = [ - 'password', - 'remember_token', - ]; + protected $hidden = []; /** * Get the attributes that should be cast. @@ -40,9 +49,65 @@ class User extends Authenticatable */ protected function casts(): array { - return [ - 'email_verified_at' => 'datetime', - 'password' => 'hashed', - ]; + return []; } + + public function tasks() + { +// return $this->belongsToMany(Tasks::class, 'pivot_tasks', 'user_id', 'task_id'); + return $this->belongsToMany( + Tasks::class, // مدل مقصد + 'pivot_tasks', // جدول واسط + 'user_id', // ستون جدول واسط که به جدول users اشاره می‌کنه + 'task_id', // ستون جدول واسط که به جدول tasks اشاره می‌کنه + 'plain_id', // ستون جدول users که ستون جدول واسط بهش اشاره می‌کنه (local key) + 'task_id' // ستون جدول tasks که ستون جدول واسط بهش اشاره می‌کنه (related key) + ); + } + + public function attendances() + { + + return $this->hasMany(Attendance::class, 'user_identity', 'user_name') + ->select('id', 'user_identity', 'entered_at', 'exited_at', 'duration','requested') + ->orderBy('entered_at', 'desc'); + + + } + public function attendanceBreaks() + { + return $this->hasManyThrough(AttendanceBreak::class,Attendance::class,'user_identity','attendance_id', + 'user_name', // local key در users + 'id' // local key در attendances + ); + } + + + public function thismonth($data) + { + + } + + public function everymonth($data) + { + $result = []; + + foreach ($data->attendances as $att) { + if ($att->entered_at) { + $date = \Morilog\Jalali\Jalalian::fromCarbon(\Carbon\Carbon::parse($att->entered_at)); + $month = $date->format('%B'); + + if (!isset($result[$month])) { + $result[$month] = []; + } + + $result[$month][] = $att; + } + } + + + return $result; + } + + } diff --git a/app/Models/ai.php b/app/Models/ai.php old mode 100644 new mode 100755 diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php old mode 100644 new mode 100755 index 452e6b65..016ca6cd --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -19,6 +19,6 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + } } diff --git a/bootstrap/app.php b/bootstrap/app.php index c1832766..11282790 100755 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -6,13 +6,31 @@ use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( - web: __DIR__.'/../routes/web.php', - commands: __DIR__.'/../routes/console.php', + web: __DIR__ . '/../routes/web.php', + commands: __DIR__ . '/../routes/console.php', + api: __DIR__ . '/../routes/api.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { - // + $middleware->group('web', [ + \Illuminate\Cookie\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + // \Illuminate\Session\Middleware\AuthenticateSession::class, + ]); + + $middleware->group('api', [ + // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + // 'throttle:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ]); + $middleware->group('admin', [ + \Illuminate\Routing\Middleware\SubstituteBindings::class + ]); }) ->withExceptions(function (Exceptions $exceptions): void { - // + })->create(); diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 1d6a810c..d1b83894 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "php": "^8.2", "laravel/framework": "^12.0", "laravel/tinker": "^2.10.1", - "morilog/jalali": "^3.4" + "morilog/jalali": "^3.4", + "predis/predis": "^3.2" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock old mode 100644 new mode 100755 index cdb81a2b..d206cca6 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a2ec9a62fadff86c2c1515530c75f8e2", + "content-hash": "611e1c3c1211e46afd5c8aa1c11d2332", "packages": [ { "name": "beberlei/assert", @@ -2714,6 +2714,69 @@ ], "time": "2024-07-20T21:41:07+00:00" }, + { + "name": "predis/predis", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/predis/predis.git", + "reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/predis/predis/zipball/9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8", + "reference": "9e9deec4dfd3ebf65d32eb368f498c646ba2ecd8", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.0|^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.3", + "phpstan/phpstan": "^1.9", + "phpunit/phpcov": "^6.0 || ^8.0", + "phpunit/phpunit": "^8.0 || ~9.4.4" + }, + "suggest": { + "ext-relay": "Faster connection with in-memory caching (>=0.6.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Till Krüss", + "homepage": "https://till.im", + "role": "Maintainer" + } + ], + "description": "A flexible and feature-complete Redis/Valkey client for PHP.", + "homepage": "http://github.com/predis/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "support": { + "issues": "https://github.com/predis/predis/issues", + "source": "https://github.com/predis/predis/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/tillkruss", + "type": "github" + } + ], + "time": "2025-08-06T06:41:24+00:00" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/config/app.php b/config/app.php old mode 100644 new mode 100755 diff --git a/config/auth.php b/config/auth.php old mode 100644 new mode 100755 diff --git a/config/cache.php b/config/cache.php old mode 100644 new mode 100755 diff --git a/config/database.php b/config/database.php old mode 100644 new mode 100755 index 5b318f58..26286ad3 --- a/config/database.php +++ b/config/database.php @@ -147,7 +147,7 @@ return [ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), + 'prefix' => "WOLOG-TEMPBASE",//env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), 'persistent' => env('REDIS_PERSISTENT', false), ], diff --git a/config/filesystems.php b/config/filesystems.php old mode 100644 new mode 100755 diff --git a/config/logging.php b/config/logging.php old mode 100644 new mode 100755 diff --git a/config/mail.php b/config/mail.php old mode 100644 new mode 100755 diff --git a/config/queue.php b/config/queue.php old mode 100644 new mode 100755 diff --git a/config/services.php b/config/services.php old mode 100644 new mode 100755 diff --git a/config/session.php b/config/session.php old mode 100644 new mode 100755 diff --git a/database/.gitignore b/database/.gitignore old mode 100644 new mode 100755 diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php old mode 100644 new mode 100755 diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/0001_01_01_000001_create_cache_table.php b/database/migrations/0001_01_01_000001_create_cache_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/0001_01_01_000002_create_jobs_table.php b/database/migrations/0001_01_01_000002_create_jobs_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2025_07_09_095044_create_attendances_table.php b/database/migrations/2025_07_09_095044_create_attendances_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2025_07_09_144052_create_attendance_breaks_table.php b/database/migrations/2025_07_09_144052_create_attendance_breaks_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2025_07_10_210036_create_ais_table.php b/database/migrations/2025_07_10_210036_create_ais_table.php old mode 100644 new mode 100755 diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php old mode 100644 new mode 100755 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 00000000..d693eea6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.8" + +services: + redis: + image: redis:7-alpine + ports: + - "6363:6379" + volumes: + - /home/liman/server/redis_data:/data + restart: always + command: ["redis-server", "--appendonly", "yes"] \ No newline at end of file diff --git a/package.json b/package.json old mode 100644 new mode 100755 diff --git a/phpunit.xml b/phpunit.xml old mode 100644 new mode 100755 diff --git a/public/info.php b/public/info.php new file mode 100644 index 00000000..61ace196 --- /dev/null +++ b/public/info.php @@ -0,0 +1,2 @@ +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, $s] = explode(':', $att->duration); + $tsec += $h * 3600 + $m * 60 + $s; + } + } + $hours = floor($tsec / 3600); + $minutes = floor(($tsec % 3600) / 60); + $seconds = $tsec % 60; + + $totalTime = sprintf('%02d:%02d', $hours, $minutes); + $user->totaltime = $totalTime; + +} +//dd($users); +foreach ($users as $u) { + + $us = $u->attendances() + ->whereNull('exited_at') + ->latest('entered_at') + ->exists(); + $u->working = $us ? 1 : 0; + + foreach ($u->attendances as $u_att) { + $break = AttendanceBreak::wherenull('break_end')->where('attendance_id', $u_att->id)->exists(); + if ($break) + $u->working = 2; + } + +} +//dd($users); +$users = $users->sortByDesc('working'); +//$users = json_decode(json: $users); +// $users = collect($users); +$usersChunked = $users->chunk(3); +//dd($users); +?> + + +@extends('app') +@section('content') +
+ + @if(!collect($reqs)->pluck('attendances')->flatten()->isEmpty()) +
+

درخواست ها

+ {{-- {{dd($reqs)}}--}} + + @foreach ($reqs as $u) + @if(!empty($u['attendances'])) + + + {{-- @else--}} + {{--

درخواستی ثبت نشده

--}} + {{-- @break--}} + @endif +
+ + + + + + + + + + + + + + + {{-- {{dd($u['attendances'])}}--}} + @forelse($u['attendances'] as $rec) + + + + + @if(Carbon::parse($rec->oldenter)->format('H:i') == Carbon::parse($rec->newenter)->format('H:i') || $rec->newenter=='') + + @else + + @endif + + @if(Carbon::parse($rec->oldexit)->format('H:i') == Carbon::parse($rec->newexit)->format('H:i') || $rec->newenter=='') + + @else + + @endif + + {{-- @if(Carbon::parse($rec->oldenter)->format('H:i') == Carbon::parse($rec->newenter)->format('H:i') || $rec->newenter=='')--}} + {{-- {{}}--}} + {{-- --}} + {{-- @else--}} + {{-- --}} + {{-- @endif--}} + {{-- @if(Carbon::parse($rec->oldexit)->format('H:i') == Carbon::parse($rec->newexit)->format('H:i') || $rec->newenter=='')--}} + {{-- --}} + {{-- @else--}} + {{-- --}} + {{-- @endif--}} + + + @empty + + + + @endforelse + +
درخواستتاریخورودخروجتعیین وضعیت
{{ match ($rec->function) { + 'edit' => "تغییر ساعت", + 'delete' => "حذف", + 'new' => "جدید", + default => "نامشخص", + } }}{{ Jalalian::fromCarbon(Carbon::parse($rec->oldenter))->format('Y/m/d') }}{{ $rec->oldenter ? Carbon::parse($rec->oldenter)->format('H:i') : '-' }}{{ $rec->oldenter ? ($rec->id=='new' || $rec->oldenter==($rec->newenter ?? '') ? Carbon::parse($rec->oldenter)->format('H:i') : Carbon::parse($rec->oldenter)->format('H:i').'👇🏻'.Carbon::parse($rec->newenter)->format('H:i')) : '-' }}{{$rec->oldexit ? Carbon::parse($rec->oldexit)->format('H:i') : '-'}}{{ $rec->oldexit ? ($rec->id=='new' || $rec->oldexit==($rec->newexit ?? '') ? Carbon::parse($rec->oldexit)->format('H:i') : Carbon::parse($rec->oldexit)->format('H:i').'👇🏻'.Carbon::parse($rec->newexit)->format('H:i')) : '-' }}{{ Carbon::parse($rec->oldenter)->format('H:i') }}{{ $rec->oldenter ? ($rec->id=='new' ? Carbon::parse($rec->oldenter)->format('H:i') :Carbon::parse($rec->oldenter)->format('H:i').'👇🏻'.Carbon::parse($rec->newenter)->format('H:i')) : '-' }} {{Carbon::parse($rec->oldexit)->format('H:i')}}{{ $rec->oldexit ? ($rec->id=='new' ? Carbon::parse($rec->oldexit)->format('H:i') :Carbon::parse($rec->oldexit)->format('H:i').'👇🏻'.$rec->newexit) : '-'}} +
+ @csrf + + + +
+
+ @csrf + + + +
+
هیچ رکوردی ثبت نشده
+
{{-- پایان hidden-content --}} + @endforeach + {{-- @if(collect($reqs)->pluck('attendances')->flatten()->isEmpty())--}} + {{--

درخواستی ثبت نشده

--}} +
+ @endif + + +
+
+ @foreach ($usersChunked as $chunk) + @foreach ($chunk as $u) + + + @endforeach + @endforeach + + + +
+ + +
+ {{-- {{dd($reqs)}}--}} + + + + {{--MODAL--}} + + @endsection + + @section('script') + + +@endsection \ No newline at end of file diff --git a/resources/views/admin/new.blade.php b/resources/views/admin/new.blade.php new file mode 100644 index 00000000..9b068d29 --- /dev/null +++ b/resources/views/admin/new.blade.php @@ -0,0 +1,58 @@ +@extends('app') +@section('content') +
+ +
+ +
+

کاربر جدید

+
+ +
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+@endsection \ No newline at end of file diff --git a/resources/views/app.blade.php b/resources/views/app.blade.php old mode 100644 new mode 100755 index 6c82023a..622677c7 --- a/resources/views/app.blade.php +++ b/resources/views/app.blade.php @@ -1,5 +1,13 @@ +where('user_name', $_COOKIE['user_identity'])->first(); +//dd($user_p); + +?> + سامانه حضور و غیاب + + {{--ساعت--}} + + + + {{--تاریخ--}} + + + + + + - - + + @yield('style') + @if (session('message')) -
- {{ session('message.text') }} -
+
+
+ {{ session('message.text') }} +
+
@endif - -
-
+
+ @if(url()->current() != url('/tasks')) +
+ + + +
+ @endif +
-
- -{{-- --}} -{{-- @if(isset($_COOKIE['token_0']) || isset($_COOKIE['token_1']) || isset($_COOKIE['token_2']))--}} -{{-- --}} -{{-- @endif--}} +
+ + + + @if(isset($_COOKIE['token-0'])) + + @else + + @endif + + + +
+
- @if(isset($attendance_recorder) and $attendance_recorder==1 or true) - - @else -
-
- @csrf - @if(isset($_COOKIE['token_0']) || isset($_COOKIE['token_1']) || isset($_COOKIE['token_2'])) - - @endif - - + {{-- @if(isset($attendance_recorder) and $attendance_recorder == 1 or true)--}} - -
-
- @endif + {{-- @else--}} +
+
+ @csrf + @if(isset($_COOKIE['token_0']) || isset($_COOKIE['token_1']) || isset($_COOKIE['token_2'])) + + @endif + {{-- attendances list--}} + @if(isset($_COOKIE['token-0'])) + + @endif + @if(isset($_COOKIE['user_identity'])) + + @endif + + + @if(!request()->is("admin") && (isset($_COOKIE['ad']) && $_COOKIE['ad']==1)) + + + @elseif(request()->is("admin") && (isset($_COOKIE['ad']) && $_COOKIE['ad']==1)) + + @endif + @if(isset($_COOKIE['user_identity'])) + + + @endif +
+
+ {{-- @endif--}} + {{-- {{dd(session('admin'))}}--}} -@yield('content') -
- -@yield('script') + + // Close modal when clicking outside the modal content + document.getElementById('modal-container').addEventListener('click', (e) => { + if (e.target === document.getElementById('modal-container')) { + closeModal() + } + }) + document.addEventListener('DOMContentLoaded', function () { + const errorBox = document.getElementById('error-box') + if (errorBox) { + // Fade out the error box after 3 seconds + setTimeout(() => { + errorBox.classList.add('opacity-0') // Add fade-out class + // Remove the error box after the fade-out transition ends + errorBox.addEventListener('transitionend', () => { + errorBox.remove() + }) + }, 3000) // Duration before starting fade out + } + }) + + @yield('script')
- - - - - - + \ No newline at end of file diff --git a/resources/views/attendance/index.blade.php b/resources/views/attendance/index.blade.php old mode 100644 new mode 100755 index aec5c9d5..b19f0df0 --- a/resources/views/attendance/index.blade.php +++ b/resources/views/attendance/index.blade.php @@ -1,313 +1,744 @@ get(); +use Illuminate\Support\Collection; + +$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)) +$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(); + ?? ai::where('key', 'angizeh')->orderByDesc('id')->first(); $ids = array_merge($ids, [$s->id]); Cookie::queue('seen_angizeh_ids', json_encode($ids), 14400); -//dd($Attendance) + +//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->attendanes)) { + 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'); +$existed = $Attendance->whereNull('exited_at')->first(); +$requested = $Attendance->whereNull('exited_at')->where('requested', 'true')->first(); +$lastday = $Attendance->whereNull('exited_at')->where('entered_at', '<', $now)->first(); +$forgot = $lastday ? Carbon::parse($lastday->entered_at)->format('Y-m-d') : ''; +//dd($lastday); + + +$hash = md5(strtolower(trim($user->email))); +$gravatarUrl = "https://www.gravatar.com/avatar/$hash?s=200&d=identicon"; + + ?> @extends('app') @section('content') -
-
- @csrf -

سامانه گذارش کار

-

- {{$s->response}} -{{-- اگر دکمه سبز یا آبی بود، ورود شما تأیید شده است.--}} -{{-- اگر نارنجی بود، خارج از محدوده هستید و ورود به‌صورت دورکاری ثبت می‌شود و نیاز به تأیید مدیر دارد.--}} -

- @php - $user_identity = $_COOKIE['user_identity'] ?? ''; - @endphp +
- - - - - - -
+ {{-- --}} + @if (!isset($_COOKIE['token-0'])) - - -
-
- - -
- - @if(isset($_COOKIE['user_identity'])) - - - - - - - - - - - - @foreach($Attendance->sortByDesc('entered_at') as $item) - - - - - - - - - - - - - @endforeach - - -
ورود - خروج - جمع - جمع استراحت -
- {{ $item->entered_at ? Jalalian::fromCarbon(Carbon::parse($item->entered_at))->format('H:i m/d') : '-' }} - - {{ $item->exited_at ? Jalalian::fromCarbon(Carbon::parse($item->exited_at))->format('H:i m/d') : '-' }} - - {{ $item->entered_at && $item->exited_at ? \Carbon\Carbon::parse($item->entered_at)->diff(\Carbon\Carbon::parse($item->exited_at))->format('%H:%I') : '-' }} - 0
- @endif - -
-
- -
- - - -