diff --git a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php index ad00239..fa76489 100644 --- a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php +++ b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php @@ -304,7 +304,7 @@ class TicketController extends Controller // 1. Tính tổng ngày phép được cấp $totalAllocated = $this->getTotalAllocatedDays($user, $year); - // 2. Tính số ngày đã nghỉ trong năm + // 2. Tính số ngày đã nghỉ có phép trong năm $usedDays = $this->getUsedLeaveDays($user, $year); // 3. Tính số ngày còn lại @@ -320,7 +320,7 @@ class TicketController extends Controller $monthsInfo = $monthlyCheckResult['months_info']; if (!empty($monthsInfo)) { //Danh sách ngày nghỉ trong tháng dựa trên list ngày xin nghỉ - + } } @@ -371,39 +371,137 @@ class TicketController extends Controller ->sum('categories.c_value'); } + //Tính tổng giới hạn ngày nghỉ có phép tối đa trong tháng + private function getMaxLeaveDaysPerMonth(): int + { + $limitLeaveMonth = Category::where('c_type', 'LIMIT_LEAVE_MONTH')->where('c_code', "LIMIT")->first(); + if ($limitLeaveMonth) { + $maxDaysPerMonth = (int)$limitLeaveMonth->c_value; + } else { + $maxDaysPerMonth = 3; // default nếu k có setting + } + return $maxDaysPerMonth; + } + private function checkMonthlyLeaveLimit($user, array $dataListPeriod): array { + // Danh sách ngày nghỉ theo tháng $requestMonths = $this->groupLeaveRequestsByMonth($dataListPeriod); $monthsInfo = []; foreach ($requestMonths as $monthKey => $monthData) { - $usedDaysInMonth = $this->getUsedLeaveDaysInMonth($user, $monthData['year'], $monthData['month']); - dd($usedDaysInMonth); - $requestMonths[$monthKey]['days_used'] = $usedDaysInMonth; - // Kiểm tra giới hạn ngày nghỉ trong tháng - $maxDaysPerMonth = 3; // Có thể điều chỉnh theo quy định công ty - $totalDaysInMonth = $usedDaysInMonth + $monthData['days_requested']; + // Tính tổng số ngày nghỉ có phép trong tháng + $usedDaysInMonth = $this->getUsedLeaveDaysInMonth($user, $monthData['year'], $monthData['month'], 'ONLEAVE'); - if ($totalDaysInMonth > $maxDaysPerMonth) { - return $this->exceedMonthlyLimitResponse($monthData, $usedDaysInMonth, $maxDaysPerMonth); - } + // Tính tổng số ngày nghỉ không phép trong tháng + $usedDaysInMonthWithoutPay = $this->getUsedLeaveDaysInMonth($user, $monthData['year'], $monthData['month'], 'LEAVE_WITHOUT_PAY'); - $monthsInfo[] = [ + // Tính tổng giới hạn ngày nghỉ có phép tối đa trong tháng + $maxDaysPerMonth = $this->getMaxLeaveDaysPerMonth(); + + // Tính tổng số ngày nghỉ trong tháng + $totalDaysInMonth = $usedDaysInMonth + $usedDaysInMonthWithoutPay + $monthData['days_requested']; + + + // Tính tổng phép có trong tháng + $totalLeaveDaysInMonth = $this->getTotalLeaveDaysInMonth($user, $monthData['year'], $monthData['month']); + + // Tính tổng số ngày nghỉ có phép đến tháng hiện tại + $totalLeaveDaysInMonthToMonth = $this->getTotalLeaveDaysInMonthToMonth($user, $monthData['year'], $monthData['month']); + + //Ngày phép còn lại trong tháng + $remainingDaysInMonth = $totalLeaveDaysInMonth - $totalLeaveDaysInMonthToMonth; + // dd($remainingDaysInMonth, $totalLeaveDaysInMonth, $totalLeaveDaysInMonthToMonth); + + $month_data = [ 'year' => $monthData['year'], 'month' => $monthData['month'], - 'days_used' => $usedDaysInMonth, - 'days_requested' => $monthData['days_requested'], - 'total_days' => $totalDaysInMonth + 'total_leave_days_in_month' => $totalLeaveDaysInMonth, //tổng số ngày phép + 'total_leave_days_in_month_to_month' => $totalLeaveDaysInMonthToMonth, // tổng ngày nghỉ có phép + 'remaining_days_in_month' => $remainingDaysInMonth, //ngày phép còn lại + 'days_used' => $usedDaysInMonth, //tổng số ngày nghỉ có phép ở tháng hiện tại + 'days_used_without_pay' => $usedDaysInMonthWithoutPay, //tổng số ngày nghỉ không phép ở tháng hiện tại + 'days_requested' => $monthData['days_requested'], //số ngày yêu cầu nghỉ của tháng ]; + + if ($remainingDaysInMonth <= 0) { //hết phép + return [ + 'success' => false, + 'message' => "Hiện tại bạn đã hết phép nghỉ trong tháng {$monthData['month']}/{$monthData['year']}\nBạn có chấp nhận nộp: " . $monthData['days_requested'] . " ngày không phép không?", + 'warning_type' => 'exceed_monthly_limit', + 'month_data' => $month_data + ]; + } else { + // Còn phép + if ($remainingDaysInMonth >= $monthData['days_requested']) { + return [ + 'success' => true, + 'message' => "Đủ ngày phép", + 'warning_type' => 'exceed_monthly_limit', + 'month_data' => $month_data + ]; + } else { + return $this->exceedMonthlyLimitResponse($remainingDaysInMonth, $monthData, $usedDaysInMonth, $usedDaysInMonthWithoutPay, $month_data); + } + } } return [ - 'success' => true, + 'success' => false, + 'message' => "Không tìm được mảng danh sách ngày nghỉ", + 'warning_type' => 'exceed_monthly_limit', 'months_info' => $monthsInfo ]; } + //Trả về thông báo vượt quá giới hạn ngày nghỉ có phép trong tháng + private function exceedMonthlyLimitResponse(float $remainingDaysInMonth, array $monthData, float $usedDaysInMonth, float $usedDaysInMonthWithoutPay, array $month_data): array + { + $daysNotEnough = $monthData['days_requested'] - $remainingDaysInMonth; + $message = "Số ngày phép còn lại: {$remainingDaysInMonth}, Số ngày yêu cầu: {$monthData['days_requested']}.\n\nBạn có chấp nhận nộp: {$remainingDaysInMonth} ngày phép và {$daysNotEnough} ngày không phép không?"; + return [ + 'success' => false, + 'message' => "Bạn không đủ ngày phép.\n\nTrong tháng {$monthData['month']}/{$monthData['year']}:\n\nBạn đã nghỉ: {$usedDaysInMonth} ngày phép, {$usedDaysInMonthWithoutPay} ngày không phép. \n\n{$message}", + 'warning_type' => 'exceed_monthly_limit', + 'month_data' => $month_data + ]; + } + + //Tính tổng số ngày nghỉ có phép đến tháng hiện tại + private function getTotalLeaveDaysInMonthToMonth($user, int $year, int $month): float + { + return Notes::join('categories', function ($join) { + $join->on('notes.n_time_type', '=', 'categories.c_code') + ->where('categories.c_type', 'TIME_TYPE'); + }) + ->where('n_user_id', $user->id) + ->where('n_year', $year) + ->where('n_month', "<=", $month) + ->where('n_reason', 'ONLEAVE') + ->sum('categories.c_value'); + } + + private function getTotalLeaveDaysInMonth($user, int $year, int $month): float + { + $leaveDaysInfo = LeaveDays::where('ld_user_id', $user->id) + ->where('ld_year', $year) + ->first(); + + $totalAllocated = 0; + if ($leaveDaysInfo) { + if ($leaveDaysInfo->ld_day_total > $month) { + $totalAllocated = $month; + } else { + $totalAllocated = $leaveDaysInfo->ld_day_total; + } + } else { + Log::warning("No LeaveDays record found for user ID: {$user->id}, year: {$year}. Assuming 0 allocated days."); + } + $totalAllocated = $totalAllocated + $leaveDaysInfo->ld_additional_day + $leaveDaysInfo->ld_special_leave_day; + return $totalAllocated; + } + private function groupLeaveRequestsByMonth(array $dataListPeriod): array { $requestMonths = []; @@ -428,7 +526,7 @@ class TicketController extends Controller return $requestMonths; } - private function getUsedLeaveDaysInMonth($user, int $year, int $month): float + private function getUsedLeaveDaysInMonth($user, int $year, int $month, string $reason): float { return Notes::join('categories', function ($join) { $join->on('notes.n_time_type', '=', 'categories.c_code') @@ -437,29 +535,10 @@ class TicketController extends Controller ->where('n_user_id', $user->id) ->where('n_year', $year) ->where('n_month', $month) - ->where('n_reason', 'ONLEAVE') + ->where('n_reason', $reason) ->sum('categories.c_value'); } - private function exceedMonthlyLimitResponse(array $monthData, float $usedDaysInMonth, int $maxDaysPerMonth): array - { - $exceedDays = ($usedDaysInMonth + $monthData['days_requested']) - $maxDaysPerMonth; - - return [ - 'success' => false, - 'message' => "Trong tháng {$monthData['month']}/{$monthData['year']}, bạn đã nghỉ {$usedDaysInMonth} ngày và xin nghỉ thêm {$monthData['days_requested']} ngày, vượt quá giới hạn {$maxDaysPerMonth} ngày/tháng. Vui lòng điều chỉnh lại.", - 'warning_type' => 'exceed_monthly_limit', - 'month_data' => [ - 'year' => $monthData['year'], - 'month' => $monthData['month'], - 'days_used' => $usedDaysInMonth, - 'days_requested' => $monthData['days_requested'], - 'max_days' => $maxDaysPerMonth, - 'exceed_days' => $exceedDays - ] - ]; - } - private function insufficientLeaveDaysResponse($user, float $remainingDays, float $daysRequested): array { $daysNotEnough = $daysRequested - $remainingDays; @@ -467,7 +546,9 @@ class TicketController extends Controller return [ 'success' => false, - 'message' => "Bạn không đủ ngày phép. Số ngày phép còn lại: {$remainingDays}, Số ngày yêu cầu: {$daysRequested}. Bạn có chấp nhận nộp: {$daysNotEnough} ngày không phép không?" + 'message' => "Bạn không đủ ngày phép. Số ngày phép còn lại: {$remainingDays}, Số ngày yêu cầu: {$daysRequested}. Bạn có chấp nhận nộp: {$daysNotEnough} ngày không phép không?", + 'warning_type' => 'insufficient_leave_days', + 'month_data' => [] ]; } diff --git a/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx b/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx index f953769..2910ead 100644 --- a/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx +++ b/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx @@ -522,7 +522,7 @@ const LeaveManagement = () => { >
0 ? 'block' : 'none', }} > - {ld_day_total} + {'Phép năm:'}{' '} + + {ld_day_total} +
0 ? 'block' : 'none', }} > - {ld_additional_day} + {'Phép năm cũ:'}{' '} + + {ld_additional_day} +
0 ? 'block' : 'none', }} > - {ld_special_leave_day} + {'Phép đặc biệt:'}{' '} + + {ld_special_leave_day} +
@@ -674,11 +706,37 @@ const LeaveManagement = () => { label={showAllOff(user.monthlyLeaveDays)} >- {totalOnLeave} +
+ {'Nghỉ phép:'}{' '} + + {totalOnLeave} +
-- {totalLeaveWithoutPay} +
+ {'Không phép:'}{' '} + + {totalLeaveWithoutPay} +