edit filter time

This commit is contained in:
2026-06-02 22:17:47 +03:30
parent 300575930f
commit 41d1036300
7 changed files with 844 additions and 250 deletions
+225 -49
View File
@@ -22,24 +22,154 @@ use App\Models\Pivot_Tasks;
class AdminController extends Controller
{
private function loadPendingRequests($users): array
private function redisIsAvailable(): bool
{
$records = [];
try {
Redis::connection()->ping();
return true;
} catch (\Throwable) {
foreach ($users as $user) {
$records[] = [
'user_name' => $user->user_name,
'name' => $user->name,
'attendances' => [],
];
return false;
}
}
private function appendDecodedRequest(array &$target, ?string $raw): void
{
if (!$raw) {
return;
}
$request = json_decode($raw);
if ($request && ($request->function ?? null) !== 'rejected') {
$target[] = $request;
}
}
private function appendDecodedRequestWithAttendance(array &$target, ?string $raw, ?Attendance $attendance = null): void
{
if (!$raw) {
return;
}
$request = json_decode($raw);
if ($request && ($request->function ?? null) !== 'rejected') {
$target[] = $this->enrichRequestForView($request, $attendance);
}
}
private function buildFallbackRequestFromAttendance(Attendance $attendance): object
{
$request = (object) [
'function' => 'edit',
'userid' => $attendance->user_identity,
'id' => $attendance->id,
'oldenter' => $attendance->entered_at ? Carbon::parse($attendance->entered_at)->format('H:i') : '',
'newenter' => '',
'oldexit' => $attendance->exited_at ? Carbon::parse($attendance->exited_at)->format('H:i') : '',
'newexit' => '',
'date' => $attendance->entered_at
? Jalalian::fromCarbon(Carbon::parse($attendance->entered_at))->format('Y/m/d')
: null,
];
$request->display_date = $this->formatRequestDisplayDate($request, $attendance);
return $request;
}
private function formatRequestDisplayDate(object $request, ?Attendance $attendance = null): string
{
$candidates = array_filter([
$attendance?->entered_at,
(!empty($request->oldenter) && str_contains((string) $request->oldenter, ' '))
? $request->oldenter
: null,
$request->date ?? null,
]);
foreach ($candidates as $value) {
try {
if (is_string($value) && preg_match('/^\d{4}\/\d{2}\/\d{2}$/', $value)) {
$year = (int) substr($value, 0, 4);
if ($year >= 1700) {
return Jalalian::fromCarbon(Carbon::createFromFormat('Y/m/d', $value))->format('Y/m/d');
}
if ($year >= 1300) {
return Jalalian::fromFormat('Y/m/d', $value)->format('Y/m/d');
}
}
$carbon = Carbon::parse($value);
if ($carbon->year >= 1000) {
return Jalalian::fromCarbon($carbon)->format('Y/m/d');
}
} catch (\Throwable) {
continue;
}
}
return '-';
}
private function enrichRequestForView(object $request, ?Attendance $attendance = null): object
{
if (!isset($request->display_date)) {
$request->display_date = $this->formatRequestDisplayDate($request, $attendance);
}
return $request;
}
private function resolveRequestTime(?string $preferred, ?string $fallback, $recordDefault = null): ?string
{
$value = ($preferred !== null && $preferred !== '') ? $preferred : $fallback;
if ($value === null || $value === '') {
if ($recordDefault) {
return Carbon::parse($recordDefault)->format('H:i:s');
}
return $records;
return null;
}
return Carbon::parse($value)->format('H:i:s');
}
private function buildAttendanceTimestamp(string $date, ?string $time): ?string
{
if (!$time) {
return null;
}
return $date . ' ' . $time;
}
private function decrementUserRequestCount(?string $userName): void
{
if (!$userName) {
return;
}
User::where('user_name', $userName)
->where('req_counts', '>', 0)
->decrement('req_counts');
}
private function loadPendingRequests($users): array
{
$userNames = $users->pluck('user_name')->filter()->values();
$redisAvailable = $this->redisIsAvailable();
$pendingByUser = Attendance::query()
->whereIn('user_identity', $userNames)
->whereNotNull('requested')
->where('requested', '!=', '')
->get(['id', 'user_identity', 'entered_at', 'exited_at'])
->groupBy('user_identity');
$records = [];
foreach ($users as $user) {
$rec = [
'user_name' => $user->user_name,
@@ -47,28 +177,58 @@ class AdminController extends Controller
'attendances' => [],
];
foreach (Redis::keys("att-tempreq:{$user->user_name}:*") as $key) {
if (str_contains($key, ':creates:')) {
continue;
$pendingForUser = $pendingByUser->get($user->user_name, collect());
$hasRequestHint = ($user->req_counts ?? 0) > 0 || $pendingForUser->isNotEmpty();
if (!$hasRequestHint) {
$records[] = $rec;
continue;
}
$loadedIds = [];
if ($redisAvailable) {
foreach (Redis::lrange("att-tempreq:creates:{$user->user_name}", 0, -1) as $reqJson) {
$this->appendDecodedRequestWithAttendance($rec['attendances'], $reqJson);
}
$raw = Redis::get($key);
if (!$raw) {
continue;
}
$this->appendDecodedRequestWithAttendance($rec['attendances'], Redis::get("att-tempreq:{$user->user_name}:new"));
$get = json_decode($raw);
if ($get && ($get->function ?? null) !== 'rejected') {
$rec['attendances'][] = $get;
if ($pendingForUser->isNotEmpty()) {
$redisKeys = $pendingForUser
->map(fn ($attendance) => "att-tempreq:{$user->user_name}:{$attendance->id}")
->values()
->all();
$rawValues = Redis::mget($redisKeys);
foreach ($pendingForUser->values() as $index => $attendance) {
$raw = $rawValues[$index] ?? null;
if (!$raw) {
continue;
}
$beforeCount = count($rec['attendances']);
$this->appendDecodedRequestWithAttendance($rec['attendances'], $raw, $attendance);
if (count($rec['attendances']) > $beforeCount) {
$loadedIds[(string) $attendance->id] = true;
}
}
}
}
$createRequests = Redis::lrange("att-tempreq:creates:{$user->user_name}", 0, -1);
foreach ($createRequests as $reqJson) {
$get = json_decode($reqJson);
if ($get && ($get->function ?? null) !== 'rejected') {
$rec['attendances'][] = $get;
foreach ($pendingForUser as $attendance) {
if (isset($loadedIds[(string) $attendance->id])) {
continue;
}
$rec['attendances'][] = $this->buildFallbackRequestFromAttendance($attendance);
}
$pendingById = $pendingForUser->keyBy('id');
foreach ($rec['attendances'] as $index => $request) {
$attendance = $pendingById->get($request->id ?? null);
$rec['attendances'][$index] = $this->enrichRequestForView($request, $attendance);
}
$records[] = $rec;
@@ -354,6 +514,7 @@ class AdminController extends Controller
// Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
$this->decrementUserRequestCount($data->userid);
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
'text' => 'رکورد با موفقیت حذف شد✔️'
@@ -371,43 +532,45 @@ class AdminController extends Controller
]);
}
} elseif ($data->function == 'edit') {
// dd($data);
$record = Attendance::find($data->id);
if (!$record) {
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
'text' => 'رکورد پیدا نشد✖️'
]);
}
$attendance = new Attendance();
$date = Carbon::parse($record->entered_at)->format('Y-m-d');
$enterTime = $this->resolveRequestTime($data->newenter ?? null, $data->oldenter ?? null, $record->entered_at);
$exitTime = $this->resolveRequestTime($data->newexit ?? null, $data->oldexit ?? null, $record->exited_at);
$record->ip_address = 'admin-edited';
$record->user_identity = $data->userid;
$record->entered_at = $data->newenter ? $date . ' ' . $data->newenter : null;
if ($data->newexit != null) {
//جریمه
// if($data->newexit > '16:00:00'){
// $data->newexit = date('H:i:s', strtotime($data->newexit . ' -1 hour'));
// }
$record->exited_at = $date . ' ' . $data->newexit;
$duration = $attendance->duration($data->newenter, $data->newexit);
$record->entered_at = $this->buildAttendanceTimestamp($date, $enterTime) ?? $record->entered_at;
if ($exitTime) {
$record->exited_at = $this->buildAttendanceTimestamp($date, $exitTime);
$duration = $attendance->duration($enterTime, $exitTime);
} else {
$record->exited_at = null;
$record->duration = null;
$duration = null;
}
$break = AttendanceBreak::where('attendance_id', $data->id)->sum('duration');
if ($break) {
if ($break && $duration) {
$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);
}
$record->duration = $duration ?? $record->duration;
//dd($record->duration, $duration, $break);
$record->requested = '';
$record->save();
// $create_requests_key = "att-tempreq:creates:{$data->userid}";
// $create_requests_key = "att-tempreq:{$data->userid}:{$data->id}";
// $t = Redis::connection()->lrem($create_requests_key, -1, json_encode($data));
Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
$this->decrementUserRequestCount($data->userid);
tel_notif($record->user_identity, "تایید");
@@ -416,21 +579,33 @@ class AdminController extends Controller
"text" => 'رکورد با موفقیت ذخیره شد.✔️'
]);
} elseif ($data->function == 'new') {
// dd($data);
$starttime = $data->oldenter ? Carbon::parse($data->oldenter)->format('H:i:s') : null;
$endtime = $data->oldexit ? Carbon::parse($data->oldexit)->format('H:i:s') : null;
$enteredAt = !empty($data->oldenter) ? Carbon::parse($data->oldenter) : null;
$exitedAt = !empty($data->oldexit) ? Carbon::parse($data->oldexit) : null;
if (!$enteredAt) {
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
'text' => 'زمان ورود در درخواست مشخص نیست✖️'
]);
}
$starttime = $enteredAt->format('H:i:s');
$endtime = $exitedAt?->format('H:i:s');
if (is_null($endtime) || $endtime > $starttime) {
$attendance = new Attendance();
$attendance->ip_address = 'admin-new';
$attendance->user_identity = $data->userid;
$attendance->entered_at = $data->oldenter ?: null;
$attendance->exited_at = $data->oldexit ?: null;
$attendance->duration = $data->oldexit ? $attendance->duration($data->oldenter, $data->oldexit) : null;
$attendance->entered_at = $enteredAt->format('Y-m-d H:i:s');
$attendance->exited_at = $exitedAt?->format('Y-m-d H:i:s');
$attendance->duration = $endtime
? $attendance->duration($starttime, $endtime)
: null;
$attendance->save();
$create_requests_key = "att-tempreq:creates:{$data->userid}";
Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
$this->decrementUserRequestCount($data->userid);
// Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
tel_notif($data->userid, "تایید");
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
@@ -456,6 +631,7 @@ class AdminController extends Controller
$att->save();
}
tel_notif($data->userid, "رد");
$this->decrementUserRequestCount($data->userid);
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'درخواست با موفقیت رد شد.✔️'