update permission display for leave management #133
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -51,7 +51,7 @@ class LeaveManagementController extends Controller
 | 
			
		|||
            )
 | 
			
		||||
            // ->where('notes.n_user_id', "1")
 | 
			
		||||
            ->where('notes.n_year', $year)
 | 
			
		||||
            ->whereIn('notes.n_reason', ['ONLEAVE', 'LEAVE_WITHOUT_PAY'])
 | 
			
		||||
            ->whereIn('notes.n_reason', ['ONLEAVE', 'LEAVE_WITHOUT_PAY', 'TEMPORARY_ONLEAVE'])
 | 
			
		||||
            // ->groupBy("notes.n_user_id")
 | 
			
		||||
            ->orderBy('notes.n_month')
 | 
			
		||||
            ->orderBy('notes.n_day')
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ class LeaveManagementController extends Controller
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // Lọc chỉ lấy user có permission bao gồm staff
 | 
			
		||||
        $staffData = $leaveDays->filter(function($user) {
 | 
			
		||||
        $staffData = $leaveDays->filter(function ($user) {
 | 
			
		||||
            return isset($user['user']['permission']) && strpos($user['user']['permission'], 'staff') !== false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -402,6 +402,10 @@ class TicketController extends Controller
 | 
			
		|||
 | 
			
		||||
        $ticket->updated_by = $admin->name;
 | 
			
		||||
        $ticket->admin_note = $request->admin_note;
 | 
			
		||||
 | 
			
		||||
        // Clear Timekeeping cache
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->start_date)->month, Carbon::parse($ticket->start_date)->year);
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->end_date)->month, Carbon::parse($ticket->end_date)->year);
 | 
			
		||||
        $ticket->save();
 | 
			
		||||
 | 
			
		||||
        return AbstractController::ResultSuccess($ticket, "Ticket updated successfully!");
 | 
			
		||||
| 
						 | 
				
			
			@ -717,6 +721,7 @@ class TicketController extends Controller
 | 
			
		|||
            ->first();
 | 
			
		||||
 | 
			
		||||
        $totalAllocated = 0;
 | 
			
		||||
        // Xử lý gửi ticket sau tháng hiện tại
 | 
			
		||||
        if ($leaveDaysInfo && $user->is_permanent) {
 | 
			
		||||
            $currentMonth = Carbon::now()->month;
 | 
			
		||||
            $totalAllocated = $leaveDaysInfo->ld_day_total;
 | 
			
		||||
| 
						 | 
				
			
			@ -837,19 +842,21 @@ class TicketController extends Controller
 | 
			
		|||
        $dataMasterTypeNotes = CategoryController::getListMasterByType("REASON_NOTES");
 | 
			
		||||
        $onleave = null;
 | 
			
		||||
        $leaveWithoutPay = null;
 | 
			
		||||
        $temporaryOnleave = null;
 | 
			
		||||
 | 
			
		||||
        if ($dataMasterTypeNotes) {
 | 
			
		||||
            // get nghỉ phép, nghỉ không phép
 | 
			
		||||
            $onleave = optional($dataMasterTypeNotes->where('c_code', 'ONLEAVE')->first())->c_code;
 | 
			
		||||
            $leaveWithoutPay = optional($dataMasterTypeNotes->where('c_code', 'LEAVE_WITHOUT_PAY')->first())->c_code;
 | 
			
		||||
            $temporaryOnleave = optional($dataMasterTypeNotes->where('c_code', 'TEMPORARY_ONLEAVE')->first())->c_code;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($onleave == null || $leaveWithoutPay == null) {
 | 
			
		||||
        if ($onleave == null || $leaveWithoutPay == null || $temporaryOnleave == null) {
 | 
			
		||||
            return response()->json(['message' => "Data reason notes not found", 'status' => false]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($action == "confirm") {
 | 
			
		||||
            $this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay);
 | 
			
		||||
            $this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay, $temporaryOnleave);
 | 
			
		||||
            return response()->json(['message' => "confirmed", 'status' => true]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -887,20 +894,22 @@ class TicketController extends Controller
 | 
			
		|||
        $dataMasterTypeNotes = CategoryController::getListMasterByType("REASON_NOTES");
 | 
			
		||||
        $onleave = null;
 | 
			
		||||
        $leaveWithoutPay = null;
 | 
			
		||||
        $temporaryOnleave = null;
 | 
			
		||||
 | 
			
		||||
        if ($dataMasterTypeNotes) {
 | 
			
		||||
            // Get nghỉ phép, nghỉ không phép
 | 
			
		||||
            $onleave = optional($dataMasterTypeNotes->where('c_code', 'ONLEAVE')->first())->c_code;
 | 
			
		||||
            $leaveWithoutPay = optional($dataMasterTypeNotes->where('c_code', 'LEAVE_WITHOUT_PAY')->first())->c_code;
 | 
			
		||||
            $temporaryOnleave = optional($dataMasterTypeNotes->where('c_code', 'TEMPORARY_ONLEAVE')->first())->c_code;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Không tìm được ngày phép, ko phép
 | 
			
		||||
        if ($onleave == null || $leaveWithoutPay == null) {
 | 
			
		||||
        if ($onleave == null || $leaveWithoutPay == null || $temporaryOnleave == null) {
 | 
			
		||||
            return redirect()->to(config('app.client_url') . '/404');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($action == "confirm") {
 | 
			
		||||
            $this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay);
 | 
			
		||||
            $this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay, $temporaryOnleave);
 | 
			
		||||
            return redirect()->to(config('app.client_url') . '/tickets-management');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -913,7 +922,7 @@ class TicketController extends Controller
 | 
			
		|||
        return redirect()->to(config('app.client_url') . '/tickets-management');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay)
 | 
			
		||||
    private function handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay, $temporaryOnleave)
 | 
			
		||||
    {
 | 
			
		||||
        $startDate = $ticket->start_date; //Start day
 | 
			
		||||
        $startPeriod = $ticket->start_period; //The session begins
 | 
			
		||||
| 
						 | 
				
			
			@ -934,6 +943,7 @@ class TicketController extends Controller
 | 
			
		|||
            $dataListPeriod = $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
 | 
			
		||||
            $balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod, null, true);
 | 
			
		||||
            // dd($balanceCheckResult, $dataListPeriod);
 | 
			
		||||
            $currentMonth = Carbon::now()->month;
 | 
			
		||||
            if ($balanceCheckResult['success'] == false) {
 | 
			
		||||
                if ($balanceCheckResult['months_info']) {
 | 
			
		||||
                    foreach ($balanceCheckResult['months_info'] as $monthInfo) {
 | 
			
		||||
| 
						 | 
				
			
			@ -960,7 +970,7 @@ class TicketController extends Controller
 | 
			
		|||
                                    'n_month' => $month,
 | 
			
		||||
                                    'n_year' => $year,
 | 
			
		||||
                                    'n_time_type' => 'S',
 | 
			
		||||
                                    'n_reason' => $onleave,
 | 
			
		||||
                                    'n_reason' => $month > $currentMonth ? $temporaryOnleave :  $onleave,
 | 
			
		||||
                                    'n_note' => $ticket->reason,
 | 
			
		||||
                                    'ticket_id' => $ticket->id
 | 
			
		||||
                                ]);
 | 
			
		||||
| 
						 | 
				
			
			@ -970,7 +980,7 @@ class TicketController extends Controller
 | 
			
		|||
                                    'n_month' => $month,
 | 
			
		||||
                                    'n_year' => $year,
 | 
			
		||||
                                    'n_time_type' => 'C',
 | 
			
		||||
                                    'n_reason' => $leaveWithoutPay,
 | 
			
		||||
                                    'n_reason' => $month > $currentMonth ? $temporaryOnleave : $leaveWithoutPay,
 | 
			
		||||
                                    'n_note' => $ticket->reason,
 | 
			
		||||
                                    'ticket_id' => $ticket->id
 | 
			
		||||
                                ]);
 | 
			
		||||
| 
						 | 
				
			
			@ -985,7 +995,7 @@ class TicketController extends Controller
 | 
			
		|||
                                    'n_month' => $month,
 | 
			
		||||
                                    'n_year' => $year,
 | 
			
		||||
                                    'n_time_type' => $period,
 | 
			
		||||
                                    'n_reason' => $onleave,
 | 
			
		||||
                                    'n_reason' => $month > $currentMonth ? $temporaryOnleave : $onleave,
 | 
			
		||||
                                    'n_note' => $ticket->reason,
 | 
			
		||||
                                    'ticket_id' => $ticket->id
 | 
			
		||||
                                ]);
 | 
			
		||||
| 
						 | 
				
			
			@ -999,7 +1009,7 @@ class TicketController extends Controller
 | 
			
		|||
                                    'n_month' => $month,
 | 
			
		||||
                                    'n_year' => $year,
 | 
			
		||||
                                    'n_time_type' => $period,
 | 
			
		||||
                                    'n_reason' => $leaveWithoutPay,
 | 
			
		||||
                                    'n_reason' => $month > $currentMonth ? $temporaryOnleave : $leaveWithoutPay,
 | 
			
		||||
                                    'n_note' => $ticket->reason,
 | 
			
		||||
                                    'ticket_id' => $ticket->id
 | 
			
		||||
                                ]);
 | 
			
		||||
| 
						 | 
				
			
			@ -1019,49 +1029,49 @@ class TicketController extends Controller
 | 
			
		|||
                        'n_month' => $month,
 | 
			
		||||
                        'n_year' => $year,
 | 
			
		||||
                        'n_time_type' => $result['period'],
 | 
			
		||||
                        'n_reason' => $onleave, // có phép
 | 
			
		||||
                        'n_reason' => $month > $currentMonth ? $temporaryOnleave : $onleave,
 | 
			
		||||
                        'n_note' => $ticket->reason,
 | 
			
		||||
                        'ticket_id' => $ticket->id
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $yearCheck = Carbon::parse($endDate)->year;
 | 
			
		||||
            // Check giá trị ld_day_total của bảng leave_days thuộc user id đó với giá trị của list item note trong bảng notes của user id đó
 | 
			
		||||
            $leaveDaysInfo = LeaveDays::where('ld_user_id', $ticket->user_id)
 | 
			
		||||
                ->where('ld_year', $yearCheck)
 | 
			
		||||
                ->first();
 | 
			
		||||
            if ($leaveDaysInfo) {
 | 
			
		||||
                // Tính tổng số ngày nghỉ có phép đã sử dụng trong năm
 | 
			
		||||
                $totalUsedLeaveDays = Notes::join('categories', function ($join) {
 | 
			
		||||
                    $join->on('notes.n_time_type', '=', 'categories.c_code')
 | 
			
		||||
                        ->where('categories.c_type', 'TIME_TYPE');
 | 
			
		||||
                })
 | 
			
		||||
                    ->where('n_user_id', $ticket->user_id)
 | 
			
		||||
                    ->where('n_year', $yearCheck)
 | 
			
		||||
                    ->where('n_reason', 'ONLEAVE')
 | 
			
		||||
                    ->sum('categories.c_value');
 | 
			
		||||
            // $yearCheck = Carbon::parse($endDate)->year;
 | 
			
		||||
            // // Check giá trị ld_day_total của bảng leave_days thuộc user id đó với giá trị của list item note trong bảng notes của user id đó
 | 
			
		||||
            // $leaveDaysInfo = LeaveDays::where('ld_user_id', $ticket->user_id)
 | 
			
		||||
            //     ->where('ld_year', $yearCheck)
 | 
			
		||||
            //     ->first();
 | 
			
		||||
            // if ($leaveDaysInfo) {
 | 
			
		||||
            //     // Tính tổng số ngày nghỉ có phép đã sử dụng trong năm
 | 
			
		||||
            //     $totalUsedLeaveDays = Notes::join('categories', function ($join) {
 | 
			
		||||
            //         $join->on('notes.n_time_type', '=', 'categories.c_code')
 | 
			
		||||
            //             ->where('categories.c_type', 'TIME_TYPE');
 | 
			
		||||
            //     })
 | 
			
		||||
            //         ->where('n_user_id', $ticket->user_id)
 | 
			
		||||
            //         ->where('n_year', $yearCheck)
 | 
			
		||||
            //         ->where('n_reason', 'ONLEAVE')
 | 
			
		||||
            //         ->sum('categories.c_value');
 | 
			
		||||
 | 
			
		||||
                // Tính tổng số ngày phép được cấp
 | 
			
		||||
                $totalAllocatedDays = $leaveDaysInfo->ld_day_total +
 | 
			
		||||
                    $leaveDaysInfo->ld_additional_day +
 | 
			
		||||
                    $leaveDaysInfo->ld_special_leave_day;
 | 
			
		||||
            //     // Tính tổng số ngày phép được cấp
 | 
			
		||||
            //     $totalAllocatedDays = $leaveDaysInfo->ld_day_total +
 | 
			
		||||
            //         $leaveDaysInfo->ld_additional_day +
 | 
			
		||||
            //         $leaveDaysInfo->ld_special_leave_day;
 | 
			
		||||
 | 
			
		||||
                // Tính số ngày vượt quá và làm tròn lên
 | 
			
		||||
                $excessDays = $totalUsedLeaveDays - $totalAllocatedDays;
 | 
			
		||||
                $roundedExcessDays = ceil($excessDays); // Làm tròn lên số nguyên gần nhất
 | 
			
		||||
            //     // Tính số ngày vượt quá và làm tròn lên
 | 
			
		||||
            //     $excessDays = $totalUsedLeaveDays - $totalAllocatedDays;
 | 
			
		||||
            //     $roundedExcessDays = ceil($excessDays); // Làm tròn lên số nguyên gần nhất
 | 
			
		||||
 | 
			
		||||
                // Kiểm tra nếu số ngày đã sử dụng vượt quá số ngày được cấp
 | 
			
		||||
                if ($roundedExcessDays > 0) {
 | 
			
		||||
                    Log::warning("User ID: {$ticket->user_id} has used more leave days ({$totalUsedLeaveDays}) than allocated ({$totalAllocatedDays})");
 | 
			
		||||
            //     // Kiểm tra nếu số ngày đã sử dụng vượt quá số ngày được cấp
 | 
			
		||||
            //     if ($roundedExcessDays > 0) {
 | 
			
		||||
            //         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
 | 
			
		||||
                    $leaveDaysInfo->ld_day_total += $roundedExcessDays;
 | 
			
		||||
                    $leaveDaysInfo->save();
 | 
			
		||||
            //         // Cập nhật cột ld_day_total với số ngày đã làm tròn
 | 
			
		||||
            //         $leaveDaysInfo->ld_day_total += $roundedExcessDays;
 | 
			
		||||
            //         $leaveDaysInfo->save();
 | 
			
		||||
 | 
			
		||||
                    Log::info("Updated leave days for User ID: {$ticket->user_id}. Added {$roundedExcessDays} days (rounded from {$excessDays})");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            //         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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1117,7 +1127,8 @@ class TicketController extends Controller
 | 
			
		|||
        $ticket['status'] = 'CONFIRMED';
 | 
			
		||||
        $ticket->save();
 | 
			
		||||
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth($month, $year);
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->start_date)->month, Carbon::parse($ticket->start_date)->year);
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->end_date)->month, Carbon::parse($ticket->end_date)->year);
 | 
			
		||||
 | 
			
		||||
        // Send notification email to users
 | 
			
		||||
        $data = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -1358,8 +1369,9 @@ class TicketController extends Controller
 | 
			
		|||
        $message = "";
 | 
			
		||||
 | 
			
		||||
        if ($index === 0) {
 | 
			
		||||
            $showMonth = $monthData['month'] > Carbon::now()->month ? $monthData['month'] : Carbon::now()->month;
 | 
			
		||||
            $message .= "* Quy định: mỗi tháng được nghỉ tối đa {$max} ngày phép\n";
 | 
			
		||||
            $message .= "- Bạn đang có: {$totalLeave} ngày phép\n\n";
 | 
			
		||||
            $message .= "- Bạn có: {$totalLeave} ngày phép (Tính tới {$showMonth}/{$monthData['year']})\n\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Hiển thị cộng phép nếu gửi ticket trong tương lai
 | 
			
		||||
| 
						 | 
				
			
			@ -1380,7 +1392,7 @@ class TicketController extends Controller
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        if ($willUseLeave > 0 || $willUseNoPay > 0) {
 | 
			
		||||
            $message .= "  - Bạn sẽ sử dụng: ";
 | 
			
		||||
            $message .= "  - Dự kiến bạn sẽ sử dụng: ";
 | 
			
		||||
            $usedParts = [];
 | 
			
		||||
            if ($willUseLeave > 0) $usedParts[] = "{$willUseLeave} phép";
 | 
			
		||||
            if ($willUseNoPay > 0) $usedParts[] = "{$willUseNoPay} không phép";
 | 
			
		||||
| 
						 | 
				
			
			@ -1478,7 +1490,6 @@ class TicketController extends Controller
 | 
			
		|||
            for ($i = 1; $i <= $month; $i++) {
 | 
			
		||||
                // Giả lập cộng phép
 | 
			
		||||
                $onleaveDaysTotal++;
 | 
			
		||||
                $ld_note = $ld_note . "Cộng phép tháng " . $i . ".\n";
 | 
			
		||||
                // $tmpOnleaveDaysTotal = $onleaveDaysTotal;
 | 
			
		||||
 | 
			
		||||
                $onleaveDaysInMonth = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,12 +171,8 @@ class TimekeepingController extends Controller
 | 
			
		|||
 | 
			
		||||
        // Validate the request
 | 
			
		||||
        $request->validate($rules);
 | 
			
		||||
 | 
			
		||||
        $id = $request->input('id');
 | 
			
		||||
 | 
			
		||||
        $month = $request->month;
 | 
			
		||||
        $year = $request->year;
 | 
			
		||||
 | 
			
		||||
        $note = Notes::find($id);
 | 
			
		||||
        if (!$note) {
 | 
			
		||||
            return response()->json(['message' => 'Note not found', 'status' => false]);
 | 
			
		||||
| 
						 | 
				
			
			@ -193,77 +189,11 @@ class TimekeepingController extends Controller
 | 
			
		|||
        $ticket->save();
 | 
			
		||||
 | 
			
		||||
        Notes::where('ticket_id', $ticket->id)->delete();
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth($month, $year);
 | 
			
		||||
 | 
			
		||||
        // Clear Timekeeping cache
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->start_date)->month, Carbon::parse($ticket->start_date)->year);
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth(Carbon::parse($ticket->end_date)->month, Carbon::parse($ticket->end_date)->year);
 | 
			
		||||
        return response()->json(['message' => 'Delete success', 'status' => true]);
 | 
			
		||||
 | 
			
		||||
        // $n_month = $note->n_month;
 | 
			
		||||
        // $n_year = $note->n_year;
 | 
			
		||||
 | 
			
		||||
        // if ($note->n_reason == "ONLEAVE") {
 | 
			
		||||
        //     // Get note reason ONLEAVE by $n_month, $n_year not include $note->id & include $note->n_user_id
 | 
			
		||||
        //     // $onleave = Notes::getNotesByMonthAndYearAndUserId($n_month, $n_year, $note->n_user_id, $note->id);
 | 
			
		||||
 | 
			
		||||
        //     // Get note reason LEAVE_WITHOUT_PAY by $n_month, $n_year & include $note->n_user_id
 | 
			
		||||
        //     $leaveWithoutPay = Notes::getNotesByMonthAndYearAndUserIdAndReason($n_month, $n_year, $note->n_user_id, 'LEAVE_WITHOUT_PAY');
 | 
			
		||||
 | 
			
		||||
        //     if (count($leaveWithoutPay) > 0) {
 | 
			
		||||
        //         $deletedValue = ($note->n_time_type === 'ALL') ? 1.0 : 0.5;
 | 
			
		||||
        //         $needUpdate = $deletedValue;
 | 
			
		||||
        //         // dd($needUpdate, $leaveWithoutPay);
 | 
			
		||||
        //         foreach ($leaveWithoutPay as $lwNote) {
 | 
			
		||||
        //             if ($needUpdate <= 0) break;
 | 
			
		||||
 | 
			
		||||
        //             if ($lwNote->n_time_type === 'ALL') {
 | 
			
		||||
        //                 if ($needUpdate == 1.0) {
 | 
			
		||||
        //                     // Chuyển cả note ALL thành phép
 | 
			
		||||
        //                     $lwNote->update(['n_reason' => 'ONLEAVE']);
 | 
			
		||||
        //                     $needUpdate = 0;
 | 
			
		||||
        //                     break;
 | 
			
		||||
        //                 } else { // $needUpdate == 0.5
 | 
			
		||||
        //                     // Tách ALL thành 2 note S và C, chuyển S thành phép, C giữ không phép
 | 
			
		||||
        //                     Notes::create([
 | 
			
		||||
        //                         'n_user_id' => $lwNote->n_user_id,
 | 
			
		||||
        //                         'n_day' => $lwNote->n_day,
 | 
			
		||||
        //                         'n_month' => $lwNote->n_month,
 | 
			
		||||
        //                         'n_year' => $lwNote->n_year,
 | 
			
		||||
        //                         'n_time_type' => 'S',
 | 
			
		||||
        //                         'n_reason' => 'ONLEAVE',
 | 
			
		||||
        //                         'n_note' => $lwNote->n_note
 | 
			
		||||
        //                     ]);
 | 
			
		||||
        //                     Notes::create([
 | 
			
		||||
        //                         'n_user_id' => $lwNote->n_user_id,
 | 
			
		||||
        //                         'n_day' => $lwNote->n_day,
 | 
			
		||||
        //                         'n_month' => $lwNote->n_month,
 | 
			
		||||
        //                         'n_year' => $lwNote->n_year,
 | 
			
		||||
        //                         'n_time_type' => 'C',
 | 
			
		||||
        //                         'n_reason' => 'LEAVE_WITHOUT_PAY',
 | 
			
		||||
        //                         'n_note' => $lwNote->n_note
 | 
			
		||||
        //                     ]);
 | 
			
		||||
        //                     $lwNote->delete();
 | 
			
		||||
        //                     $needUpdate = 0;
 | 
			
		||||
        //                     break;
 | 
			
		||||
        //                 }
 | 
			
		||||
        //             } else {
 | 
			
		||||
        //                 // Nếu $lwNote->n_time_type == 'S' hoặc 'C' => 0.5
 | 
			
		||||
        //                 if ($needUpdate == 1.0) {
 | 
			
		||||
        //                     // Chuyển cả note ALL thành phép
 | 
			
		||||
        //                     $lwNote->update(['n_reason' => 'ONLEAVE']);
 | 
			
		||||
        //                     $needUpdate -= 0.5;
 | 
			
		||||
        //                 } else { // $needUpdate == 0.5
 | 
			
		||||
        //                     // S hoặc C, chỉ cần chuyển đúng 0.5 ngày
 | 
			
		||||
        //                     $lwNote->update(['n_reason' => 'ONLEAVE']);
 | 
			
		||||
        //                     $needUpdate = 0;
 | 
			
		||||
        //                     break;
 | 
			
		||||
        //                 }
 | 
			
		||||
        //             }
 | 
			
		||||
        //         }
 | 
			
		||||
        //     } else {
 | 
			
		||||
        //         // Khi note phép và k tồn tại nghỉ không phép => phép + dồn cho tháng sau
 | 
			
		||||
        //     }
 | 
			
		||||
        // }
 | 
			
		||||
        // $note->delete();
 | 
			
		||||
        // $this->createOrUpdateRecordForCurrentMonth($month, $year);
 | 
			
		||||
        // return response()->json(['message' => 'Delete success', 'status' => true]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function export(Request $request)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,4 +21,4 @@ class AddMonthlyLeaveDaysCommand extends Command
 | 
			
		|||
        $year = $this->argument('year');
 | 
			
		||||
        AddMonthlyLeaveDays::dispatch($month, $year);
 | 
			
		||||
    }
 | 
			
		||||
} 
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
use App\Jobs\UpdateTemporaryLeaveDays;
 | 
			
		||||
 | 
			
		||||
class UpdateTemporaryLeaveDaysCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected $signature = 'update:temporary-leavedays {month?} {year?}';
 | 
			
		||||
    protected $description = 'Tính lại ngày phép cho các note tạm.';
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $month = $this->argument('month');
 | 
			
		||||
        $year = $this->argument('year');
 | 
			
		||||
        UpdateTemporaryLeaveDays::dispatch($month, $year);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,8 +34,9 @@ class Kernel extends ConsoleKernel
 | 
			
		|||
        // Chạy buổi chiều lúc 17:30
 | 
			
		||||
        $schedule->command('attendance:check C')->dailyAt('17:30');
 | 
			
		||||
 | 
			
		||||
        // Chạy vào 00:01 ngày đầu tiên của mỗi tháng
 | 
			
		||||
        // Chạy vào ngày đầu tiên của mỗi tháng
 | 
			
		||||
        $schedule->command('add:monthly-leavedays')->monthlyOn(1, '00:01');
 | 
			
		||||
        $schedule->command('update:temporary-leavedays')->monthlyOn(1, '00:05');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,16 +65,6 @@ class AddMonthlyLeaveDays implements ShouldQueue
 | 
			
		|||
            $permanentMonth = Carbon::parse($user->permanent_date)->month;
 | 
			
		||||
            if ($this->month > $leaveDay->ld_day_total - ($permanentDefault - $permanentMonth)) {
 | 
			
		||||
              $leaveDay->ld_day_total += self::ONLEAVE_PER_MONTH;
 | 
			
		||||
 | 
			
		||||
              // Xử lý ghi chú
 | 
			
		||||
              $newNote = "Cộng phép tháng " . $leaveDay->ld_day_total . ".\n";
 | 
			
		||||
              if (!empty($leaveDay->ld_note)) {
 | 
			
		||||
                // Nếu đã có ghi chú, thêm ghi chú mới vào và xuống dòng
 | 
			
		||||
                $leaveDay->ld_note = $leaveDay->ld_note . "\n" . $newNote;
 | 
			
		||||
              } else {
 | 
			
		||||
                // Nếu chưa có ghi chú, gán ghi chú mới
 | 
			
		||||
                $leaveDay->ld_note = $newNote;
 | 
			
		||||
              }
 | 
			
		||||
              $leaveDay->save();
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -84,16 +74,6 @@ class AddMonthlyLeaveDays implements ShouldQueue
 | 
			
		|||
        if ($leaveDay->ld_day_total < $this->month) {
 | 
			
		||||
          // Cộng mỗi tháng 1 ngày phép cho nhân viên
 | 
			
		||||
          $leaveDay->ld_day_total += self::ONLEAVE_PER_MONTH;
 | 
			
		||||
 | 
			
		||||
          // Xử lý ghi chú
 | 
			
		||||
          $newNote = "Cộng phép tháng " . $leaveDay->ld_day_total . ".\n";
 | 
			
		||||
          if (!empty($leaveDay->ld_note)) {
 | 
			
		||||
            // Nếu đã có ghi chú, thêm ghi chú mới vào và xuống dòng
 | 
			
		||||
            $leaveDay->ld_note = $leaveDay->ld_note . "\n" . $newNote;
 | 
			
		||||
          } else {
 | 
			
		||||
            // Nếu chưa có ghi chú, gán ghi chú mới
 | 
			
		||||
            $leaveDay->ld_note = $newNote;
 | 
			
		||||
          }
 | 
			
		||||
          $leaveDay->save();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,220 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs;
 | 
			
		||||
 | 
			
		||||
use App\Models\LeaveDays;
 | 
			
		||||
use App\Models\Notes;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
use Modules\Admin\app\Models\Category;
 | 
			
		||||
 | 
			
		||||
class UpdateTemporaryLeaveDays implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
    protected $month;
 | 
			
		||||
    protected $year;
 | 
			
		||||
 | 
			
		||||
    public function __construct($month = null, $year = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->month = $month ?? Carbon::now()->month;
 | 
			
		||||
        $this->year = $year ?? Carbon::now()->year;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $users = User::get();
 | 
			
		||||
 | 
			
		||||
        foreach ($users as $user) {
 | 
			
		||||
            $leaveDay = LeaveDays::where('ld_user_id', $user->id)
 | 
			
		||||
                ->where('ld_year', $this->year)
 | 
			
		||||
                ->first();
 | 
			
		||||
 | 
			
		||||
            $notes = Notes::where('n_reason', 'TEMPORARY_ONLEAVE')
 | 
			
		||||
                ->where('n_user_id', $user->id)
 | 
			
		||||
                ->where('n_year', $this->year)
 | 
			
		||||
                ->where('n_month', $this->month)
 | 
			
		||||
                ->whereExists(function ($query) use ($user) {
 | 
			
		||||
                    $query->select(DB::raw(1))
 | 
			
		||||
                        ->from('tickets')
 | 
			
		||||
                        ->where('tickets.user_id', $user->id)
 | 
			
		||||
                        ->where('tickets.status', 'CONFIRMED')
 | 
			
		||||
                        ->where('tickets.type', 'ONLEAVE');
 | 
			
		||||
                })
 | 
			
		||||
                ->get();
 | 
			
		||||
 | 
			
		||||
            $maxDaysPerMonth = $this->getMaxLeaveDaysPerMonth();
 | 
			
		||||
 | 
			
		||||
            // Tổng ngày nghỉ sẽ dùng trong tháng
 | 
			
		||||
            $willUsedDaysInMonth = 0;
 | 
			
		||||
            foreach ($notes as $note) {
 | 
			
		||||
                $willUsedDaysInMonth += $note->n_time_type == 'ALL' ? 1.0 : 0.5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Tổng phép đang có
 | 
			
		||||
            $onleaveDaysTotal = $leaveDay->ld_day_total +  $leaveDay->ld_additional_day + $leaveDay->ld_special_leave_day;
 | 
			
		||||
            // Phép đã sử dụng tới tháng hiện tại
 | 
			
		||||
            $usedOnleaveDaysTotal = 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', $this->year)
 | 
			
		||||
                ->where('n_month',  "<=", $this->month)
 | 
			
		||||
                ->where('n_reason', 'ONLEAVE')
 | 
			
		||||
                ->sum('categories.c_value');
 | 
			
		||||
            // Phép còn lại
 | 
			
		||||
            $remainingOnleaveDays = $onleaveDaysTotal - $usedOnleaveDaysTotal;
 | 
			
		||||
 | 
			
		||||
            // Log::debug("User {$user->name}\n");
 | 
			
		||||
            // Log::debug(
 | 
			
		||||
            //     "📊 Thống kê ngày phép:\n" .
 | 
			
		||||
            //         " - Tháng: {$this->month}\n" .
 | 
			
		||||
            //         " - Tổng ngày nghỉ sẽ dùng trong tháng: $willUsedDaysInMonth\n" .
 | 
			
		||||
            //         " - Tổng ngày phép: $onleaveDaysTotal\n" .
 | 
			
		||||
            //         " - Tổng ngày phép đã nghỉ: $usedOnleaveDaysTotal\n" .
 | 
			
		||||
            //         " - Tổng ngày phép còn lại: $remainingOnleaveDays\n"
 | 
			
		||||
            // );
 | 
			
		||||
 | 
			
		||||
            $onleave_days_will_use = 0; // Ngày phép sẽ dùng
 | 
			
		||||
            $nopay_days_will_use = 0;   // Ngày ko phép sẽ dùng
 | 
			
		||||
 | 
			
		||||
            // Ngày phép còn lại <= 0 (Hết phép)
 | 
			
		||||
            if ($remainingOnleaveDays <= 0) {
 | 
			
		||||
                $onleave_days_will_use = 0;
 | 
			
		||||
                $nopay_days_will_use = $willUsedDaysInMonth;
 | 
			
		||||
 | 
			
		||||
                Log::debug("--- Hết phép trong tháng ---");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Ngày phép còn lại < ngày yêu cầu (Không đủ phép)
 | 
			
		||||
            else if ($remainingOnleaveDays < $willUsedDaysInMonth) {
 | 
			
		||||
                // Vượt limit
 | 
			
		||||
                if ($willUsedDaysInMonth > $maxDaysPerMonth) {
 | 
			
		||||
                    // Phép còn lại > limit
 | 
			
		||||
                    if ($remainingOnleaveDays > $maxDaysPerMonth) {
 | 
			
		||||
                        $onleave_days_will_use = $maxDaysPerMonth;
 | 
			
		||||
                        $nopay_days_will_use = $willUsedDaysInMonth - $maxDaysPerMonth;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Phép còn lại < limit
 | 
			
		||||
                    else {
 | 
			
		||||
                        $onleave_days_will_use = $remainingOnleaveDays;
 | 
			
		||||
                        $nopay_days_will_use = $willUsedDaysInMonth - $remainingOnleaveDays;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Log::debug("--- Không đủ phép trong tháng, vượt quá limit ---",);
 | 
			
		||||
                }
 | 
			
		||||
                // Không vượt limit
 | 
			
		||||
                else {
 | 
			
		||||
                    $onleave_days_will_use = $remainingOnleaveDays;
 | 
			
		||||
                    $nopay_days_will_use = $willUsedDaysInMonth - $remainingOnleaveDays;
 | 
			
		||||
 | 
			
		||||
                    Log::debug("--- Không đủ phép trong tháng, ko vượt limit ---");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Ngày phép còn lại >= ngày yêu cầu (Đủ phép)
 | 
			
		||||
            else {
 | 
			
		||||
                // Vượt limit
 | 
			
		||||
                if ($willUsedDaysInMonth > $maxDaysPerMonth) {
 | 
			
		||||
                    $onleave_days_will_use = $maxDaysPerMonth;
 | 
			
		||||
                    $nopay_days_will_use = $willUsedDaysInMonth - $maxDaysPerMonth;
 | 
			
		||||
 | 
			
		||||
                    Log::debug("--- Đủ phép, vượt limit ---");
 | 
			
		||||
                }
 | 
			
		||||
                // Không vượt limit
 | 
			
		||||
                else {
 | 
			
		||||
                    $onleave_days_will_use = $willUsedDaysInMonth;
 | 
			
		||||
                    $nopay_days_will_use = 0;
 | 
			
		||||
 | 
			
		||||
                    Log::debug("--- Đủ phép ---");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Log::debug("", [
 | 
			
		||||
                "Phep" => $onleave_days_will_use,
 | 
			
		||||
                "Khong Phep" => $nopay_days_will_use
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            // Có nghỉ không phép 
 | 
			
		||||
            if ($nopay_days_will_use > 0) {
 | 
			
		||||
                foreach ($notes as $note) {
 | 
			
		||||
                    $value = ($note->n_time_type === 'ALL') ? 1.0 : 0.5;
 | 
			
		||||
 | 
			
		||||
                    if ($note->n_time_type === 'ALL' && $onleave_days_will_use == 0.5) {
 | 
			
		||||
                        // Chỉ còn 0.5 phép, chia thành 2 bản ghi: 1 phép, 1 không phép
 | 
			
		||||
                        // Ưu tiên phép cho buổi sáng (S), không phép cho buổi chiều (C)
 | 
			
		||||
 | 
			
		||||
                        Notes::create([
 | 
			
		||||
                            'n_user_id' => $user->id,
 | 
			
		||||
                            'n_day' => $note->n_day,
 | 
			
		||||
                            'n_month' => $note->n_month,
 | 
			
		||||
                            'n_year' => $note->n_year,
 | 
			
		||||
                            'n_time_type' => 'S',
 | 
			
		||||
                            'n_reason' => 'ONLEAVE',
 | 
			
		||||
                            'n_note' => $note->n_note,
 | 
			
		||||
                            'ticket_id' => $note->ticket_id
 | 
			
		||||
                        ]);
 | 
			
		||||
                        Notes::create([
 | 
			
		||||
                            'n_user_id' => $user->id,
 | 
			
		||||
                            'n_day' => $note->n_day,
 | 
			
		||||
                            'n_month' => $note->n_month,
 | 
			
		||||
                            'n_year' => $note->n_year,
 | 
			
		||||
                            'n_time_type' => 'C',
 | 
			
		||||
                            'n_reason' => 'LEAVE_WITHOUT_PAY',
 | 
			
		||||
                            'n_note' => $note->n_note,
 | 
			
		||||
                            'ticket_id' => $note->ticket_id
 | 
			
		||||
                        ]);
 | 
			
		||||
 | 
			
		||||
                        $note->delete();
 | 
			
		||||
 | 
			
		||||
                        $onleave_days_will_use = 0;
 | 
			
		||||
                        $nopay_days_will_use -= 0.5;
 | 
			
		||||
                    } elseif ($onleave_days_will_use > 0) {
 | 
			
		||||
                        // Dùng ngày phép trước
 | 
			
		||||
                        $use = min($onleave_days_will_use, $value);
 | 
			
		||||
                        $note->update([
 | 
			
		||||
                            'n_reason' => "ONLEAVE"
 | 
			
		||||
                        ]);
 | 
			
		||||
                        $onleave_days_will_use -= $use;
 | 
			
		||||
                    } elseif ($nopay_days_will_use > 0) {
 | 
			
		||||
                        // Hết phép, chuyển sang không phép
 | 
			
		||||
                        $use = min($nopay_days_will_use,  $value);
 | 
			
		||||
                        $note->update([
 | 
			
		||||
                            'n_reason' => "LEAVE_WITHOUT_PAY"
 | 
			
		||||
                        ]);
 | 
			
		||||
                        $nopay_days_will_use -= $use;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Đủ phép
 | 
			
		||||
            else {
 | 
			
		||||
                foreach ($notes as $note) {
 | 
			
		||||
                    $note->update([
 | 
			
		||||
                        'n_reason' => "ONLEAVE"
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        DB::table('categories')->insert([
 | 
			
		||||
            [
 | 
			
		||||
                'c_code' => 'TEMPORARY_ONLEAVE',
 | 
			
		||||
                'c_name' => 'Nghỉ dự kiến',
 | 
			
		||||
                'c_type' => 'REASON_NOTES',
 | 
			
		||||
                'c_value' => "",
 | 
			
		||||
                'c_active' => 1,
 | 
			
		||||
                'created_at' => now(),
 | 
			
		||||
                'updated_at' => now(),
 | 
			
		||||
            ],
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        DB::table('categories')->where('c_code', 'TEMPORARY_ONLEAVE')->delete();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ import {
 | 
			
		|||
} from '@mantine/core'
 | 
			
		||||
import { useDisclosure } from '@mantine/hooks'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import { IconEdit, IconFileExcel } from '@tabler/icons-react'
 | 
			
		||||
import { IconEdit, IconFileExcel, IconHelpCircle } from '@tabler/icons-react'
 | 
			
		||||
import classes from './LeaveManagement.module.css'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
| 
						 | 
				
			
			@ -294,14 +294,17 @@ const LeaveManagement = () => {
 | 
			
		|||
    return monthInYear.map((d, i) => {
 | 
			
		||||
      let totalOnLeaveMonth = 0
 | 
			
		||||
      let totalLeaveWithoutPayMonth = 0
 | 
			
		||||
      let totalTempMonth = 0
 | 
			
		||||
 | 
			
		||||
      monthlyLeaveDays
 | 
			
		||||
        .filter((item) => item.month === d.value)
 | 
			
		||||
        .map((item) => {
 | 
			
		||||
          if (item.reason_code === 'ONLEAVE') {
 | 
			
		||||
            totalOnLeaveMonth += Number(item.leave_days)
 | 
			
		||||
          } else {
 | 
			
		||||
          } else if (item.reason_code === 'LEAVE_WITHOUT_PAY') {
 | 
			
		||||
            totalLeaveWithoutPayMonth += Number(item.leave_days)
 | 
			
		||||
          } else {
 | 
			
		||||
            totalTempMonth += Number(item.leave_days)
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -665,9 +668,11 @@ const LeaveManagement = () => {
 | 
			
		|||
 | 
			
		||||
                    let onleaveDaysInMonth: MonthlyLeaveDays[] = []
 | 
			
		||||
                    let nopayDaysInMonth: MonthlyLeaveDays[] = []
 | 
			
		||||
                    let tempDaysInMonth: MonthlyLeaveDays[] = []
 | 
			
		||||
 | 
			
		||||
                    let totalOnLeaveMonth = 0
 | 
			
		||||
                    let totalLeaveWithoutPayMonth = 0
 | 
			
		||||
                    let totalTempMonth = 0
 | 
			
		||||
                    let usedAdditionalDay = 0
 | 
			
		||||
 | 
			
		||||
                    user.monthlyLeaveDays
 | 
			
		||||
| 
						 | 
				
			
			@ -676,9 +681,12 @@ const LeaveManagement = () => {
 | 
			
		|||
                        if (item.reason_code === 'ONLEAVE') {
 | 
			
		||||
                          totalOnLeaveMonth += Number(item.leave_days)
 | 
			
		||||
                          onleaveDaysInMonth.push(item)
 | 
			
		||||
                        } else {
 | 
			
		||||
                        } else if (item.reason_code === 'LEAVE_WITHOUT_PAY') {
 | 
			
		||||
                          totalLeaveWithoutPayMonth += Number(item.leave_days)
 | 
			
		||||
                          nopayDaysInMonth.push(item)
 | 
			
		||||
                        } else {
 | 
			
		||||
                          totalTempMonth += Number(item.leave_days)
 | 
			
		||||
                          tempDaysInMonth.push(item)
 | 
			
		||||
                        }
 | 
			
		||||
                      })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -703,6 +711,7 @@ const LeaveManagement = () => {
 | 
			
		|||
                    return (
 | 
			
		||||
                      <Table.Td
 | 
			
		||||
                        bg={total > 0 ? '#ffb5b5' : ''}
 | 
			
		||||
                        opacity={d.value > currentMonth ? 0.6 : 1}
 | 
			
		||||
                        key={i}
 | 
			
		||||
                        ta={'center'}
 | 
			
		||||
                      >
 | 
			
		||||
| 
						 | 
				
			
			@ -757,10 +766,51 @@ const LeaveManagement = () => {
 | 
			
		|||
                                  </Stack>
 | 
			
		||||
                                </Box>
 | 
			
		||||
                              )}
 | 
			
		||||
 | 
			
		||||
                              {totalTempMonth > 0 && (
 | 
			
		||||
                                <Box mt={6}>
 | 
			
		||||
                                  <Group align="center">
 | 
			
		||||
                                    <Text fw={500} c="blue" size="sm" mb={3}>
 | 
			
		||||
                                      Nghỉ dự kiến: {totalTempMonth}
 | 
			
		||||
                                    </Text>
 | 
			
		||||
 | 
			
		||||
                                    <Tooltip
 | 
			
		||||
                                      multiline
 | 
			
		||||
                                      opened
 | 
			
		||||
                                      position="right"
 | 
			
		||||
                                      label={
 | 
			
		||||
                                        <Text size="xs">
 | 
			
		||||
                                          Ngày nghỉ đã được duyệt, sẽ tính phép
 | 
			
		||||
                                          khi đến tháng nghỉ.
 | 
			
		||||
                                        </Text>
 | 
			
		||||
                                      }
 | 
			
		||||
                                      offset={{ mainAxis: 15 }}
 | 
			
		||||
                                    >
 | 
			
		||||
                                      <Text fw={500} c="blue">
 | 
			
		||||
                                        <IconHelpCircle
 | 
			
		||||
                                          width={15}
 | 
			
		||||
                                          height={15}
 | 
			
		||||
                                        />
 | 
			
		||||
                                      </Text>
 | 
			
		||||
                                    </Tooltip>
 | 
			
		||||
                                  </Group>
 | 
			
		||||
 | 
			
		||||
                                  <Stack gap={2} pl="md">
 | 
			
		||||
                                    {tempDaysInMonth?.map(
 | 
			
		||||
                                      (itemDay: any, indexDay: number) => (
 | 
			
		||||
                                        <Text size="xs" key={indexDay}>
 | 
			
		||||
                                          • {itemDay.time_type_name} (
 | 
			
		||||
                                          {itemDay.day}/{itemDay.month})
 | 
			
		||||
                                        </Text>
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    )}
 | 
			
		||||
                                  </Stack>
 | 
			
		||||
                                </Box>
 | 
			
		||||
                              )}
 | 
			
		||||
                            </Box>
 | 
			
		||||
                          }
 | 
			
		||||
                        >
 | 
			
		||||
                          <p>{total === 0 ? '' : total}</p>
 | 
			
		||||
                          <Text size="sm">{total === 0 ? '' : total}</Text>
 | 
			
		||||
                        </Tooltip>
 | 
			
		||||
                      </Table.Td>
 | 
			
		||||
                    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,6 +79,7 @@ const Tickets = () => {
 | 
			
		|||
  const [item, setItem] = useState({ id: 0 })
 | 
			
		||||
  const [activeBtn, setActiveBtn] = useState(false)
 | 
			
		||||
  const [disableBtn, setDisableBtn] = useState(false)
 | 
			
		||||
  const [isFetchData, setIsFetch] = useState(false)
 | 
			
		||||
 | 
			
		||||
  const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
 | 
			
		||||
  const [dataReason, setDataReason] = useState<DataReason[]>([])
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +110,8 @@ const Tickets = () => {
 | 
			
		|||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const fetchData = async () => {
 | 
			
		||||
      setIsFetch(true)
 | 
			
		||||
 | 
			
		||||
      const resultTimeType = await getListMasterByType('TIME_TYPE')
 | 
			
		||||
      setDataTimeType(
 | 
			
		||||
        resultTimeType.filter((item: DataTimeType) => item.c_code !== 'ALL'),
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +119,8 @@ const Tickets = () => {
 | 
			
		|||
 | 
			
		||||
      const resultReason = await getListMasterByType('REASON')
 | 
			
		||||
      setDataReason(resultReason)
 | 
			
		||||
 | 
			
		||||
      setIsFetch(false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fetchData()
 | 
			
		||||
| 
						 | 
				
			
			@ -369,6 +374,7 @@ const Tickets = () => {
 | 
			
		|||
            setAction('add')
 | 
			
		||||
            form.reset()
 | 
			
		||||
          }}
 | 
			
		||||
          disabled={isFetchData}
 | 
			
		||||
        >
 | 
			
		||||
          + Add
 | 
			
		||||
        </Button>
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +560,8 @@ const Tickets = () => {
 | 
			
		|||
                if (confirmValues) {
 | 
			
		||||
                  try {
 | 
			
		||||
                    setConfirmLoading(true)
 | 
			
		||||
                    action === 'add' && (await handleCreate(confirmValues, true))
 | 
			
		||||
                    action === 'add' &&
 | 
			
		||||
                      (await handleCreate(confirmValues, true))
 | 
			
		||||
                    setConfirmLoading(false)
 | 
			
		||||
                    setConfirmModal(false)
 | 
			
		||||
                  } catch (error) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue