equest for leave

This commit is contained in:
2026-07-26 10:49:48 +03:30
parent c54038d986
commit 280d2748f9
9 changed files with 608 additions and 11 deletions
+61 -2
View File
@@ -4,6 +4,7 @@ namespace App\Services;
use App\Models\Attendance;
use App\Models\LatePeriodFine;
use App\Models\LeaveRequest;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Collection;
@@ -17,7 +18,7 @@ class LatePenaltyService
public const WEEKLY_ALLOWANCE_MINUTES = 15;
public const FINE_PER_MINUTE = 2000;
public function calculateFromEnteredAt(?string $enteredAt): array
public function calculateFromEnteredAt(?string $enteredAt, ?string $userIdentity = null): array
{
if (!$enteredAt) {
return [
@@ -32,6 +33,21 @@ class LatePenaltyService
$entered = Carbon::parse($enteredAt)->startOfMinute();
$threshold = $entered->copy()->setTimeFromTimeString(self::WORK_START)->startOfMinute();
if ($userIdentity) {
$leaveThreshold = $this->approvedLeaveWorkThreshold($userIdentity, $entered);
if ($leaveThreshold === false) {
return [
'late_minutes' => 0,
'grace_late_minutes' => 0,
'daily_fine_minutes' => 0,
'daily_fine_amount' => 0,
];
}
if ($leaveThreshold instanceof Carbon) {
$threshold = $leaveThreshold->copy()->startOfMinute();
}
}
if ($entered->lte($threshold)) {
return [
'late_minutes' => 0,
@@ -54,6 +70,49 @@ class LatePenaltyService
];
}
/**
* مرخصی تأییدشده: false = معاف کامل، Carbon = شروع مؤثر کار، null = بدون تغییر.
*/
public function approvedLeaveWorkThreshold(string $userIdentity, Carbon $entered): Carbon|false|null
{
$day = $entered->toDateString();
$workStart = $entered->copy()->setTimeFromTimeString(self::WORK_START)->startOfMinute();
$leaves = LeaveRequest::query()
->where('user_identity', $userIdentity)
->where('status', 'approved')
->whereDate('date_from', '<=', $day)
->whereDate('date_to', '>=', $day)
->get();
$latestMorningLeaveEnd = null;
foreach ($leaves as $leave) {
if ($leave->type === 'daily') {
return false;
}
if ($leave->type !== 'hourly' || !$leave->time_from || !$leave->time_to) {
continue;
}
$leaveStart = Carbon::parse($day . ' ' . $leave->time_from)->startOfMinute();
$leaveEnd = Carbon::parse($day . ' ' . $leave->time_to)->startOfMinute();
// مرخصی صبح که شروع کار را پوشش می‌دهد
if ($leaveStart->lte($workStart) && $leaveEnd->gt($workStart)) {
if ($entered->lte($leaveEnd)) {
return false;
}
if ($latestMorningLeaveEnd === null || $leaveEnd->gt($latestMorningLeaveEnd)) {
$latestMorningLeaveEnd = $leaveEnd;
}
}
}
return $latestMorningLeaveEnd;
}
/** دقایق تأخیر داخل بازه ۸:۳۰–۸:۴۵ برای یک رکورد */
public function graceLateMinutes(Attendance $att): int
{
@@ -94,7 +153,7 @@ class LatePenaltyService
return $attendance;
}
$calc = $this->calculateFromEnteredAt($attendance->entered_at);
$calc = $this->calculateFromEnteredAt($attendance->entered_at, $attendance->user_identity);
$attendance->late_minutes = $calc['late_minutes'];
$attendance->daily_fine_minutes = $calc['daily_fine_minutes'];
$attendance->daily_fine_amount = $calc['daily_fine_amount'];