truong-leave-day #124
|
|
@ -220,15 +220,16 @@ class TicketController extends Controller
|
|||
$start_date = Carbon::create($startDate)->setTimezone(env('TIME_ZONE'));
|
||||
$end_date = Carbon::create($endDate)->setTimezone(env('TIME_ZONE'));
|
||||
|
||||
// --- Chỉ kiểm tra ngày phép khi loại là ONLEAVE ---
|
||||
if ($type === 'ONLEAVE' && !$isAccept) {
|
||||
// Get mảng ngày nghỉ
|
||||
$dataListPeriod = $this->getAllPeriodNew($start_date, $startPeriod, $end_date, $endPeriod);
|
||||
if (empty($dataListPeriod)) {
|
||||
return AbstractController::ResultError('Không thể tính toán khoảng thời gian nghỉ hợp lệ.');
|
||||
}
|
||||
|
||||
// --- Chỉ kiểm tra ngày phép khi loại là ONLEAVE ---
|
||||
if ($type === 'ONLEAVE' && !$isAccept) {
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái WAITING
|
||||
$ticketsWaiting = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->where('type', 'ONLEAVE')
|
||||
$ticketsWaiting = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->whereIn('type', ['ONLEAVE'])
|
||||
->get();
|
||||
$dataListPeriodWaiting = [];
|
||||
if ($ticketsWaiting->count() > 0) {
|
||||
|
|
@ -240,7 +241,7 @@ class TicketController extends Controller
|
|||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái CONFIRMED
|
||||
$ticketsConfirmed = Ticket::where('user_id', $user->id)
|
||||
->where('status', 'CONFIRMED')
|
||||
->whereIn('type', ['ONLEAVE'])
|
||||
->whereIn('type', ['ONLEAVE', 'WFH'])
|
||||
->where(function ($query) use ($start_date, $end_date) {
|
||||
$query->where(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 1: start_date nằm trong khoảng
|
||||
|
|
@ -352,6 +353,62 @@ class TicketController extends Controller
|
|||
|
||||
return AbstractController::ResultError("Không thỏa mãn điều kiện ngày phép", $balanceCheckResult);
|
||||
}
|
||||
} else if ($type === 'WFH') {
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái CONFIRMED
|
||||
$ticketsConfirmed = Ticket::where('user_id', $user->id)
|
||||
->where('status', 'CONFIRMED')
|
||||
->whereIn('type', ['ONLEAVE', 'WFH'])
|
||||
->where(function ($query) use ($start_date, $end_date) {
|
||||
$query->where(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 1: start_date nằm trong khoảng
|
||||
$q->whereBetween(DB::raw('DATE(start_date)'), [$start_date->toDateString(), $end_date->toDateString()]);
|
||||
})
|
||||
->orWhere(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 2: end_date nằm trong khoảng
|
||||
$q->whereBetween(DB::raw('DATE(end_date)'), [$start_date->toDateString(), $end_date->toDateString()]);
|
||||
})
|
||||
->orWhere(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 3: Khoảng thời gian được chọn nằm trong khoảng của ticket
|
||||
$q->where(DB::raw('DATE(start_date)'), '<=', $start_date->toDateString())
|
||||
->where(DB::raw('DATE(end_date)'), '>=', $end_date->toDateString());
|
||||
});
|
||||
})
|
||||
->get();
|
||||
|
||||
$dataListPeriodConfirmed = [];
|
||||
if ($ticketsConfirmed->count() > 0) {
|
||||
foreach ($ticketsConfirmed as $ticket) {
|
||||
$dataListPeriodConfirmed = array_merge($dataListPeriodConfirmed, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
// dd($dataListPeriodConfirmed,$ticketsConfirmed,$start_date->toDateString(),$end_date->toDateString());
|
||||
// Chuyển đổi mảng đa chiều thành mảng chuỗi để có thể so sánh
|
||||
$periodStrings = [];
|
||||
$waitingPeriodStrings = [];
|
||||
$confirmedPeriodStrings = [];
|
||||
|
||||
foreach ($dataListPeriod as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$periodStrings[] = $period['date'] . '_S';
|
||||
$periodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$periodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodConfirmed as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_S';
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đã được duyệt
|
||||
if (count(array_intersect($periodStrings, $confirmedPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket được duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
}
|
||||
// --- Kết thúc kiểm tra ---
|
||||
|
||||
|
|
@ -405,11 +462,11 @@ class TicketController extends Controller
|
|||
* @param array|null $dataListPeriod Danh sách các ngày xin nghỉ [['date' => 'Y-m-d', 'period' => 'ALL|S|C'], ...]
|
||||
* @return array Kết quả kiểm tra ['success' => bool, 'message' => string|null, ...]
|
||||
*/
|
||||
private function checkLeaveBalance($user, ?array $dataListPeriod = null, ?array $monthsInfoWaiting = null): array
|
||||
private function checkLeaveBalance($user, ?array $dataListPeriod = null, ?array $monthsInfoWaiting = null, ?bool $isAccept = false): array
|
||||
{
|
||||
// Kiểm tra giới hạn nghỉ phép theo tháng
|
||||
if (!empty($dataListPeriod)) {
|
||||
return $this->checkMonthlyLeaveLimit($user, $dataListPeriod, $monthsInfoWaiting);
|
||||
return $this->checkMonthlyLeaveLimit($user, $dataListPeriod, $monthsInfoWaiting, $isAccept);
|
||||
}
|
||||
|
||||
// Đủ điều kiện
|
||||
|
|
@ -460,7 +517,7 @@ class TicketController extends Controller
|
|||
return $maxDaysPerMonth;
|
||||
}
|
||||
|
||||
private function checkMonthlyLeaveLimit($user, array $dataListPeriod, ?array $monthsInfoWaiting = null): array
|
||||
private function checkMonthlyLeaveLimit($user, array $dataListPeriod, ?array $monthsInfoWaiting = null, ?bool $isAccept = false): array
|
||||
{
|
||||
// Danh sách ngày nghỉ theo tháng
|
||||
$requestMonths = $this->groupLeaveRequestsByMonth($dataListPeriod);
|
||||
|
|
@ -491,7 +548,7 @@ class TicketController extends Controller
|
|||
$totalDaysInMonth = $usedDaysInMonth + $usedDaysInMonthWithoutPay + $monthData['days_requested'];
|
||||
|
||||
// Tổng phép có trong tháng
|
||||
$totalLeaveDaysInMonth = $this->getTotalLeaveDaysInMonth($user, $monthData['year'], $monthData['month']);
|
||||
$totalLeaveDaysInMonth = $this->getTotalLeaveDaysInMonth($user, $monthData['year'], $monthData['month'], $isAccept);
|
||||
|
||||
// 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']);
|
||||
|
|
@ -535,7 +592,6 @@ class TicketController extends Controller
|
|||
$days_will_use_without_pay = $daysNotEnough;
|
||||
} else if (
|
||||
$remainingDaysInMonthRemaining >= $monthData['days_requested']
|
||||
// || $remainingDaysInMonthIsUsed + $monthData['days_requested'] > $maxDaysPerMonth
|
||||
) { // Đủ ngày phép ở tháng đó
|
||||
// 1. Check thêm rule 1 tháng chỉ được nghỉ tối đa $maxDaysPerMonth ngày có phép, ngày vượt sẽ là ngày không phép
|
||||
if ($totalDaysInMonth > $maxDaysPerMonth) {
|
||||
|
|
@ -627,7 +683,7 @@ class TicketController extends Controller
|
|||
->sum('categories.c_value');
|
||||
}
|
||||
|
||||
private function getTotalLeaveDaysInMonth($user, int $year, int $month): float
|
||||
private function getTotalLeaveDaysInMonth($user, int $year, int $month, ?bool $isAccept = false): float
|
||||
{
|
||||
$leaveDaysInfo = LeaveDays::where('ld_user_id', $user->id)
|
||||
->where('ld_year', $year)
|
||||
|
|
@ -640,8 +696,15 @@ class TicketController extends Controller
|
|||
// } else {
|
||||
$totalAllocated = $leaveDaysInfo->ld_day_total;
|
||||
// }
|
||||
// $totalAllocated = $month; //(+ tạm để check)
|
||||
|
||||
// Nếu là duyệt ticket thì sẽ cộng thêm số ngày phép còn lại của tháng hiện tại
|
||||
if ($isAccept) {
|
||||
if ($month >= $totalAllocated) {
|
||||
$totalAllocated += $month - $totalAllocated;
|
||||
}
|
||||
}
|
||||
// bên hàm duyệt ticket sẽ check lại để + 1 ngày trước job để đảm bảo đủ ngày phép
|
||||
|
||||
} else {
|
||||
Log::warning("No LeaveDays record found for user ID: {$user->id}, year: {$year}. Assuming 0 allocated days.");
|
||||
}
|
||||
|
|
@ -770,7 +833,7 @@ class TicketController extends Controller
|
|||
if ($action == "confirm") {
|
||||
if ($ticket->type == "ONLEAVE") {
|
||||
$dataListPeriod = $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||
$balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod);
|
||||
$balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod, null, true);
|
||||
// dd($balanceCheckResult, $dataListPeriod);
|
||||
if ($balanceCheckResult['success'] == false) {
|
||||
if ($balanceCheckResult['months_info']) {
|
||||
|
|
@ -889,14 +952,12 @@ class TicketController extends Controller
|
|||
Log::warning("User ID: {$ticket->user_id} has used more leave days ({$totalUsedLeaveDays}) than allocated ({$totalAllocatedDays})");
|
||||
|
||||
// Cập nhật cột ld_day_total với số ngày đã làm tròn
|
||||
if ($roundedExcessDays > 0) {
|
||||
$leaveDaysInfo->ld_day_total += $roundedExcessDays;
|
||||
$leaveDaysInfo->save();
|
||||
|
||||
Log::info("Updated leave days for User ID: {$ticket->user_id}. Added {$roundedExcessDays} days (rounded from {$excessDays})");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($ticket->type == "WFH") {
|
||||
$dataListPeriod = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||
foreach ($dataListPeriod as $result) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue