Thực hiện chức năng ngày phép
This commit is contained in:
		
							parent
							
								
									2cc8472bc6
								
							
						
					
					
						commit
						2fdd687fc9
					
				| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Jobs\InitializeLeaveDays;
 | 
			
		||||
use App\Models\LeaveDays;
 | 
			
		||||
use App\Models\Notes;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Validator;
 | 
			
		||||
 | 
			
		||||
class LeaveManagementController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $yearNow = $request->query('year', now()->year);
 | 
			
		||||
        $year = $request->year ?? $yearNow;
 | 
			
		||||
 | 
			
		||||
        $leaveDays = self::getDataByYear($year);
 | 
			
		||||
        if ($leaveDays->count() == 0) {
 | 
			
		||||
            InitializeLeaveDays::dispatch($year);
 | 
			
		||||
            $leaveDays = self::getDataByYear($year);
 | 
			
		||||
        }
 | 
			
		||||
        return AbstractController::ResultSuccess($leaveDays);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDataByYear($year)
 | 
			
		||||
    {
 | 
			
		||||
        $totalLeaveDaysByMonth = Notes::join('categories', function ($join) {
 | 
			
		||||
            $join->on('notes.n_time_type', '=', 'categories.c_code')
 | 
			
		||||
                ->where('categories.c_type', 'TIME_TYPE');
 | 
			
		||||
        })
 | 
			
		||||
            ->select(
 | 
			
		||||
                DB::raw('notes.n_user_id as n_user_id'),
 | 
			
		||||
                DB::raw('notes.n_year as year'),
 | 
			
		||||
                DB::raw('notes.n_month as month'),
 | 
			
		||||
                DB::raw('SUM(categories.c_value) as leave_days')
 | 
			
		||||
            )
 | 
			
		||||
            ->where('notes.n_year', $year)
 | 
			
		||||
            ->where('notes.n_reason', 'ONLEAVE')
 | 
			
		||||
            ->groupBy("notes.n_user_id", DB::raw('notes.n_month'), DB::raw('notes.n_year'))
 | 
			
		||||
            ->get()
 | 
			
		||||
            ->map(function ($item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    "n_user_id" => $item->n_user_id,
 | 
			
		||||
                    "month" => $item->month,
 | 
			
		||||
                    "leave_days" => $item->leave_days
 | 
			
		||||
                ];
 | 
			
		||||
            })
 | 
			
		||||
            ->toArray();
 | 
			
		||||
 | 
			
		||||
        $leaveDays = LeaveDays::join('users', 'leave_days.ld_user_id', '=', 'users.id')
 | 
			
		||||
            ->select(
 | 
			
		||||
                'leave_days.*',
 | 
			
		||||
                'users.id as user_id',
 | 
			
		||||
                'users.name as user_name',
 | 
			
		||||
                'users.email',
 | 
			
		||||
                'users.created_at as user_created_at',
 | 
			
		||||
                'users.permission',
 | 
			
		||||
                'users.updated_at as user_updated_at',
 | 
			
		||||
                'users.remember_token',
 | 
			
		||||
                'users.email_verified_at'
 | 
			
		||||
            )
 | 
			
		||||
            ->where('leave_days.ld_year', $year)
 | 
			
		||||
            ->get()
 | 
			
		||||
            ->map(function ($item) use ($totalLeaveDaysByMonth) {
 | 
			
		||||
 | 
			
		||||
                $monthlyLeaveDays = [];
 | 
			
		||||
                foreach ($totalLeaveDaysByMonth as $key => $totalDays) {
 | 
			
		||||
                    if ($item->ld_user_id == $totalDays["n_user_id"]) {
 | 
			
		||||
                        $monthlyLeaveDays[] = $totalDays;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return [
 | 
			
		||||
                    'user' => [
 | 
			
		||||
                        'id' => $item->user_id,
 | 
			
		||||
                        'name' => $item->user_name,
 | 
			
		||||
                        'email' => $item->email,
 | 
			
		||||
                        'created_at' => $item->user_created_at,
 | 
			
		||||
                        'permission' => $item->permission,
 | 
			
		||||
                        'updated_at' => $item->user_updated_at,
 | 
			
		||||
                        'remember_token' => $item->remember_token,
 | 
			
		||||
                        'email_verified_at' => $item->email_verified_at,
 | 
			
		||||
                    ],
 | 
			
		||||
                    'leaveDay' => [
 | 
			
		||||
                        'id' => $item->id,
 | 
			
		||||
                        'ld_user_id' => $item->ld_user_id,
 | 
			
		||||
                        'ld_day' => $item->ld_day,
 | 
			
		||||
                        'ld_year' => $item->ld_year,
 | 
			
		||||
                        'ld_date_additional' => $item->ld_date_additional,
 | 
			
		||||
                        'ld_note' => $item->ld_note,
 | 
			
		||||
                        'created_at' => $item->created_at,
 | 
			
		||||
                        'updated_at' => $item->updated_at,
 | 
			
		||||
                    ],
 | 
			
		||||
                    'monthlyLeaveDays' => $monthlyLeaveDays,
 | 
			
		||||
                ];
 | 
			
		||||
            });
 | 
			
		||||
        return $leaveDays;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function saveNoteLeave(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $validator = Validator::make($request->all(), [
 | 
			
		||||
            'totalLeave' => 'required|numeric|min:0|max:20',
 | 
			
		||||
            // 'dayAdditional' => 'required|numeric|min:0|max:20',
 | 
			
		||||
            // 'note' => 'required|string|max:255',
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        if ($validator->fails()) {
 | 
			
		||||
            return AbstractController::ResultError($validator->errors());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $validatedData = $request->all();
 | 
			
		||||
        $leaveDays = LeaveDays::find($validatedData['id']);
 | 
			
		||||
 | 
			
		||||
        $leaveDays->ld_day = $validatedData['totalLeave'];
 | 
			
		||||
        $leaveDays->ld_date_additional = $validatedData['dayAdditional']; // Assuming you have this field to store additional days
 | 
			
		||||
        $leaveDays->ld_note = $validatedData['note'];
 | 
			
		||||
 | 
			
		||||
        $leaveDays->save();
 | 
			
		||||
 | 
			
		||||
        return response()->json(['status' => true, 'message' => 'Updated successfully']);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ use Modules\Admin\app\Http\Controllers\CountryController;
 | 
			
		|||
use Modules\Admin\app\Http\Controllers\CustomThemeController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\DashboardController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\JiraController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\LeaveManagementController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\SettingController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\TimekeepingController;
 | 
			
		||||
use Modules\Admin\app\Http\Controllers\TrackingController;
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +127,14 @@ Route::middleware('api')
 | 
			
		|||
                Route::get('/get-list-master', [CategoryController::class, 'getListMaster']);
 | 
			
		||||
    
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            Route::group([
 | 
			
		||||
                'prefix' => 'leave-management',
 | 
			
		||||
            ], function () {
 | 
			
		||||
                Route::get('/', [LeaveManagementController::class, 'get'])->middleware('check.permission:admin.hr.staff');
 | 
			
		||||
                Route::post('/saveNoteLeave', [LeaveManagementController::class, 'saveNoteLeave'])->middleware('check.permission:admin.hr');
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
use App\Jobs\DeductLeaveDays;
 | 
			
		||||
 | 
			
		||||
class DeductLeaveDaysCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected $signature = 'leave:deduct {year?}';
 | 
			
		||||
    protected $description = 'Trừ đi số ngày nghỉ thêm vào năm hiện tại';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new command instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the console command.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $year = $this->argument('year');
 | 
			
		||||
        DeductLeaveDays::dispatch($year);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Console\Commands;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Console\Command;
 | 
			
		||||
use App\Jobs\InitializeLeaveDays;
 | 
			
		||||
 | 
			
		||||
class InitializeLeaveDaysCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected $signature = 'initialize:leavedays {year?}';
 | 
			
		||||
    protected $description = 'Initialize leave days for users';
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $year = $this->argument('year');
 | 
			
		||||
        InitializeLeaveDays::dispatch($year);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,11 +2,17 @@
 | 
			
		|||
 | 
			
		||||
namespace App\Console;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\DeductLeaveDays;
 | 
			
		||||
use Illuminate\Console\Scheduling\Schedule;
 | 
			
		||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
 | 
			
		||||
 | 
			
		||||
class Kernel extends ConsoleKernel
 | 
			
		||||
{
 | 
			
		||||
    protected $commands = [
 | 
			
		||||
        \App\Console\Commands\InitializeLeaveDaysCommand::class,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Define the application's command schedule.
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +22,10 @@ class Kernel extends ConsoleKernel
 | 
			
		|||
        // Chạy command 'daily:api-call' vào mỗi ngày lúc 9h sáng
 | 
			
		||||
        // $schedule->command('daily:api-call')
 | 
			
		||||
        // ->dailyAt('18:00');
 | 
			
		||||
 | 
			
		||||
        // Chạy command vào ngày 31/12 lúc 23:59:59 mỗi năm
 | 
			
		||||
        $schedule->command('initialize:leavedays')->yearlyOn(12, 31, '23:59:59');
 | 
			
		||||
        $schedule->command('leave:deduct')->yearlyOn(3, 31, '23:59:59');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +33,7 @@ class Kernel extends ConsoleKernel
 | 
			
		|||
     */
 | 
			
		||||
    protected function commands(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->load(__DIR__.'/Commands');
 | 
			
		||||
        $this->load(__DIR__ . '/Commands');
 | 
			
		||||
 | 
			
		||||
        require base_path('routes/console.php');
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
<?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 Illuminate\Support\Facades\DB;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
 | 
			
		||||
class DeductLeaveDays implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
    protected $year;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($year = null)
 | 
			
		||||
    {
 | 
			
		||||
        // Nếu không có năm được truyền vào, sử dụng năm hiện tại
 | 
			
		||||
        $this->year = $year ?? Carbon::now()->year;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $users = User::get();
 | 
			
		||||
        foreach ($users as $user) {
 | 
			
		||||
            $existingData = LeaveDays::where('ld_user_id', $user->id)
 | 
			
		||||
                ->where('ld_year', $this->year)
 | 
			
		||||
                ->where('ld_date_additional', ">", 0)
 | 
			
		||||
                ->first();
 | 
			
		||||
            if (!$existingData) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $totalLeaveDaysByMonth = Notes::join('categories', function ($join) {
 | 
			
		||||
                $join->on('notes.n_time_type', '=', 'categories.c_code')
 | 
			
		||||
                    ->where('categories.c_type', 'TIME_TYPE');
 | 
			
		||||
            })
 | 
			
		||||
                ->select(
 | 
			
		||||
                    DB::raw('notes.n_user_id as n_user_id'),
 | 
			
		||||
                    DB::raw('notes.n_year as year'),
 | 
			
		||||
                    DB::raw('SUM(categories.c_value) as leave_days')
 | 
			
		||||
                )
 | 
			
		||||
                ->where('notes.n_year', $this->year)
 | 
			
		||||
                ->where('notes.n_user_id', $user->id)
 | 
			
		||||
                ->where('notes.n_reason', 'ONLEAVE')
 | 
			
		||||
                ->groupBy(DB::raw('notes.n_year'))
 | 
			
		||||
                ->first();
 | 
			
		||||
                
 | 
			
		||||
            if ($totalLeaveDaysByMonth) {
 | 
			
		||||
                //Nếu ngày phép thừa năm trước chưa sử dụng hết => cập nhật lại ngày đó 
 | 
			
		||||
                if ($existingData->ld_date_additional > $totalLeaveDaysByMonth->leave_days) {
 | 
			
		||||
                    LeaveDays::where('ld_year', $this->year)
 | 
			
		||||
                        ->where('ld_user_id', $user->id)
 | 
			
		||||
                        ->update([
 | 
			
		||||
                            'ld_date_additional' => $totalLeaveDaysByMonth->leave_days,
 | 
			
		||||
                        ]);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                LeaveDays::where('ld_year', $this->year)
 | 
			
		||||
                    ->where('ld_user_id', $user->id)
 | 
			
		||||
                    ->update([
 | 
			
		||||
                        'ld_date_additional' => "0",
 | 
			
		||||
                    ]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
<?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 Illuminate\Support\Facades\DB;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
 | 
			
		||||
class InitializeLeaveDays implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
 | 
			
		||||
    protected $year;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($year = null)
 | 
			
		||||
    {
 | 
			
		||||
        // Nếu không có năm được truyền vào, sử dụng năm hiện tại
 | 
			
		||||
        $this->year = $year ?? Carbon::now()->year;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     */
 | 
			
		||||
    public function handle(): void
 | 
			
		||||
    {
 | 
			
		||||
        $users = User::get();
 | 
			
		||||
        $ld_day = 12;
 | 
			
		||||
        foreach ($users as $user) {
 | 
			
		||||
            // Kiểm tra xem dữ liệu của user này đã tồn tại cho năm hiện tại chưa
 | 
			
		||||
            $existingData = LeaveDays::where('ld_user_id', $user->id)
 | 
			
		||||
                ->where('ld_year', $this->year)
 | 
			
		||||
                ->first();
 | 
			
		||||
 | 
			
		||||
            if ($existingData) {
 | 
			
		||||
                // Nếu dữ liệu đã tồn tại, bỏ qua user này
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Kiểm tra dữ liệu của user này trong năm trước
 | 
			
		||||
            $previousYearData = LeaveDays::where('ld_user_id', $user->id)
 | 
			
		||||
                ->where('ld_year', $this->year - 1)
 | 
			
		||||
                ->first();
 | 
			
		||||
 | 
			
		||||
            $ld_date_additional = 0;
 | 
			
		||||
            $ld_note = '';
 | 
			
		||||
 | 
			
		||||
            if ($previousYearData) {
 | 
			
		||||
                $ld_date_additional = $previousYearData->ld_day;
 | 
			
		||||
                $totalLeaveDaysByMonth = Notes::join('categories', function ($join) {
 | 
			
		||||
                    $join->on('notes.n_time_type', '=', 'categories.c_code')
 | 
			
		||||
                        ->where('categories.c_type', 'TIME_TYPE');
 | 
			
		||||
                })
 | 
			
		||||
                    ->select(
 | 
			
		||||
                        DB::raw('notes.n_user_id as n_user_id'),
 | 
			
		||||
                        DB::raw('notes.n_year as year'),
 | 
			
		||||
                        DB::raw('SUM(categories.c_value) as leave_days')
 | 
			
		||||
                    )
 | 
			
		||||
                    ->where('notes.n_year', $this->year - 1)
 | 
			
		||||
                    ->where('notes.n_user_id', $user->id)
 | 
			
		||||
                    ->where('notes.n_reason', 'ONLEAVE')
 | 
			
		||||
                    ->groupBy(DB::raw('notes.n_year'))
 | 
			
		||||
                    ->first();
 | 
			
		||||
                if ($totalLeaveDaysByMonth) {
 | 
			
		||||
                    $ld_date_additional = $ld_date_additional - $totalLeaveDaysByMonth->leave_days;
 | 
			
		||||
                    if ($ld_date_additional < 0) {
 | 
			
		||||
                        $ld_date_additional = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                $ld_note = 'Cộng dồn ngày phép năm cũ';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Tạo dữ liệu cho năm hiện tại
 | 
			
		||||
            LeaveDays::insert([
 | 
			
		||||
                'ld_user_id' => $user->id,
 | 
			
		||||
                'ld_day' => $ld_day,
 | 
			
		||||
                'ld_year' => $this->year,
 | 
			
		||||
                'ld_date_additional' => $ld_date_additional,
 | 
			
		||||
                'ld_note' => $ld_note,
 | 
			
		||||
                'created_at' => now(),
 | 
			
		||||
                'updated_at' => now(),
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
 | 
			
		||||
class LeaveDays extends Model
 | 
			
		||||
{
 | 
			
		||||
    use HasFactory;
 | 
			
		||||
 | 
			
		||||
    protected $fillable = [
 | 
			
		||||
        'id', 'ld_user_id', 'ld_day', 'ld_year', 'ld_date_additional', 'ld_note'
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    protected $table = 'leave_days';
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -19,9 +19,6 @@ return new class extends Migration
 | 
			
		|||
            $table->float('ld_date_additional')->default(0);
 | 
			
		||||
            $table->text('ld_note')->nullable();
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
 | 
			
		||||
            // Nếu cần khóa ngoại, uncomment dòng dưới và điều chỉnh tên bảng và cột phù hợp
 | 
			
		||||
            // $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,3 +72,7 @@ export const updateWorkingDays = API_URL + 'v1/admin/timekeeping/update-working-
 | 
			
		|||
 | 
			
		||||
//Category
 | 
			
		||||
export const getListMaster = API_URL + 'v1/admin/category/get-list-master'
 | 
			
		||||
 | 
			
		||||
//LeaveManagement
 | 
			
		||||
export const getLeaveManagement = API_URL + 'v1/admin/leave-management'
 | 
			
		||||
export const updateNoteLeave = API_URL + 'v1/admin/leave-management/saveNoteLeave'
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ import {
 | 
			
		|||
  Text,
 | 
			
		||||
  TextInput,
 | 
			
		||||
  useComputedColorScheme,
 | 
			
		||||
  useMantineColorScheme
 | 
			
		||||
  useMantineColorScheme,
 | 
			
		||||
} from '@mantine/core'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,8 @@ import {
 | 
			
		|||
  IconReport,
 | 
			
		||||
  IconScan,
 | 
			
		||||
  IconSubtask,
 | 
			
		||||
  IconSun
 | 
			
		||||
  IconSun,
 | 
			
		||||
  IconCalendarClock,
 | 
			
		||||
} from '@tabler/icons-react'
 | 
			
		||||
import { useCallback, useEffect, useState } from 'react'
 | 
			
		||||
import { useLocation, useNavigate } from 'react-router-dom'
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +40,11 @@ const data = [
 | 
			
		|||
  { link: '/timekeeping', label: 'Timekeeping', icon: IconCalendar },
 | 
			
		||||
  { link: '/tracking', label: 'Check in/out', icon: IconScan },
 | 
			
		||||
  { link: '/worklogs', label: 'Worklogs', icon: IconReport },
 | 
			
		||||
  {
 | 
			
		||||
    link: '/leave-management',
 | 
			
		||||
    label: 'Leave Management',
 | 
			
		||||
    icon: IconCalendarClock,
 | 
			
		||||
  },
 | 
			
		||||
  // { link: '/jira', label: 'Jira', icon: IconSubtask },
 | 
			
		||||
  // { link: '/custom-theme', label: 'Custom Theme', icon: IconBrush },
 | 
			
		||||
  // { link: '/general-setting', label: 'General Setting', icon: IconSettings },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
.title {
 | 
			
		||||
  background-color: light-dark(var(white), var(--mantine-color-dark-7));
 | 
			
		||||
  z-index: 100;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-lg)
 | 
			
		||||
    var(--mantine-spacing-sm);
 | 
			
		||||
  border-bottom: solid rgba(201, 201, 201, 0.377) 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.optionIcon {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-evenly;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.deleteIcon {
 | 
			
		||||
  color: red;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
  border-radius: 25%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.deleteIcon:hover {
 | 
			
		||||
  background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editIcon {
 | 
			
		||||
  color: rgb(9, 132, 132);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
  border-radius: 25%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editIcon:hover {
 | 
			
		||||
  background-color: rgba(203, 203, 203, 0.809);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dialog {
 | 
			
		||||
  background-color: light-dark(white, #2d353c);
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  border: solid 1px rgb(255, 145, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dialogText {
 | 
			
		||||
  color: light-dark(#2d353c, white);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tableTr:hover {
 | 
			
		||||
  background-color: rgb(205, 255, 255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.popoverFooter {
 | 
			
		||||
  margin-top: 5px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: end;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.historyRow td {
 | 
			
		||||
  padding-top: 5px;
 | 
			
		||||
  padding-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,465 @@
 | 
			
		|||
import { getLeaveManagement, updateNoteLeave } from '@/api/Admin'
 | 
			
		||||
import { update } from '@/rtk/helpers/CRUD'
 | 
			
		||||
import { get } from '@/rtk/helpers/apiService'
 | 
			
		||||
import {
 | 
			
		||||
  Box,
 | 
			
		||||
  Button,
 | 
			
		||||
  Drawer,
 | 
			
		||||
  Menu,
 | 
			
		||||
  Select,
 | 
			
		||||
  Table,
 | 
			
		||||
  Text,
 | 
			
		||||
  Textarea,
 | 
			
		||||
  TextInput,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from '@mantine/core'
 | 
			
		||||
import { useDisclosure } from '@mantine/hooks'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import moment from 'moment'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
 | 
			
		||||
import { IconEdit } from '@tabler/icons-react'
 | 
			
		||||
 | 
			
		||||
import classes from './LeaveManagement.module.css'
 | 
			
		||||
 | 
			
		||||
interface User {
 | 
			
		||||
  id: number
 | 
			
		||||
  name: string
 | 
			
		||||
  email: string
 | 
			
		||||
  email_verified_at: string | null
 | 
			
		||||
  permission: string
 | 
			
		||||
  remember_token: string | null
 | 
			
		||||
  created_at: string | null
 | 
			
		||||
  updated_at: string | null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface LeaveDay {
 | 
			
		||||
  id: number
 | 
			
		||||
  ld_user_id: number
 | 
			
		||||
  ld_year: number
 | 
			
		||||
  ld_day: number
 | 
			
		||||
  ld_date_additional: number
 | 
			
		||||
  ld_note: string
 | 
			
		||||
  created_at: string | null
 | 
			
		||||
  updated_at: string | null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface MonthlyLeaveDays {
 | 
			
		||||
  month: number
 | 
			
		||||
  leave_days: number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface UserData {
 | 
			
		||||
  user: User
 | 
			
		||||
  leaveDay: LeaveDay
 | 
			
		||||
  monthlyLeaveDays: MonthlyLeaveDays[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const LeaveManagement = () => {
 | 
			
		||||
  const [opened1, { open: open1, close: close1 }] = useDisclosure(false)
 | 
			
		||||
  const [disableBtn, setDisableBtn] = useState(false)
 | 
			
		||||
  const monthInYear = getMonthNames()
 | 
			
		||||
  const [customAddNotes, setCustomAddNotes] = useState<{
 | 
			
		||||
    id: number
 | 
			
		||||
    user: {
 | 
			
		||||
      id: number
 | 
			
		||||
      name: string
 | 
			
		||||
    }
 | 
			
		||||
    note: string
 | 
			
		||||
    totalLeave: string
 | 
			
		||||
    dayAdditional: string
 | 
			
		||||
  }>({
 | 
			
		||||
    id: 0,
 | 
			
		||||
    user: {
 | 
			
		||||
      id: 0,
 | 
			
		||||
      name: '',
 | 
			
		||||
    },
 | 
			
		||||
    note: '',
 | 
			
		||||
    totalLeave: '',
 | 
			
		||||
    dayAdditional: '',
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const [data, setData] = useState<UserData[]>([])
 | 
			
		||||
  const [date, setDate] = useState({
 | 
			
		||||
    year: new Date().getFullYear().toString(),
 | 
			
		||||
  })
 | 
			
		||||
  const getLeaveList = async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      const res = await get(getLeaveManagement, {
 | 
			
		||||
        year: date.year,
 | 
			
		||||
      })
 | 
			
		||||
      if (res.status) {
 | 
			
		||||
        setData(
 | 
			
		||||
          res.data.filter((u: UserData) => u.user.permission.includes('staff')),
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
    } catch (error: any) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
      notifications.show({
 | 
			
		||||
        title: 'Error',
 | 
			
		||||
        message: error.message ?? error,
 | 
			
		||||
        color: 'red',
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    getLeaveList()
 | 
			
		||||
  }, [date])
 | 
			
		||||
 | 
			
		||||
  const updateInfoNote = async (
 | 
			
		||||
    id: number,
 | 
			
		||||
    users: {
 | 
			
		||||
      id: number
 | 
			
		||||
      name: string
 | 
			
		||||
    },
 | 
			
		||||
    totalLeave: string,
 | 
			
		||||
    dayAdditional: string,
 | 
			
		||||
    note: string,
 | 
			
		||||
  ) => {
 | 
			
		||||
    try {
 | 
			
		||||
      await update(
 | 
			
		||||
        updateNoteLeave,
 | 
			
		||||
        {
 | 
			
		||||
          id: id,
 | 
			
		||||
          users: users,
 | 
			
		||||
          totalLeave: totalLeave,
 | 
			
		||||
          dayAdditional: dayAdditional,
 | 
			
		||||
          note: note,
 | 
			
		||||
        },
 | 
			
		||||
        getLeaveList,
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      setDisableBtn(false)
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getMonthNames() {
 | 
			
		||||
    const monthNames = [
 | 
			
		||||
      {
 | 
			
		||||
        value: 1,
 | 
			
		||||
        name: 'January',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 2,
 | 
			
		||||
        name: 'February',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 3,
 | 
			
		||||
        name: 'March',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 4,
 | 
			
		||||
        name: 'April',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 5,
 | 
			
		||||
        name: 'May',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 6,
 | 
			
		||||
        name: 'June',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 7,
 | 
			
		||||
        name: 'July',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 8,
 | 
			
		||||
        name: 'August',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 9,
 | 
			
		||||
        name: 'September',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 10,
 | 
			
		||||
        name: 'October',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 11,
 | 
			
		||||
        name: 'November',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        value: 12,
 | 
			
		||||
        name: 'December',
 | 
			
		||||
      },
 | 
			
		||||
    ]
 | 
			
		||||
    return monthNames.map((month) => {
 | 
			
		||||
      return {
 | 
			
		||||
        value: month.value,
 | 
			
		||||
        name: month.name.substring(0, 3),
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // console.log(customAddNotes, 'customAddNotes')
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
      <div className={classes.title}>
 | 
			
		||||
        <h3>
 | 
			
		||||
          <Text>Admin/</Text> Leave Management
 | 
			
		||||
        </h3>
 | 
			
		||||
      </div>
 | 
			
		||||
      <Drawer
 | 
			
		||||
        opened={opened1}
 | 
			
		||||
        onClose={close1}
 | 
			
		||||
        position="right"
 | 
			
		||||
        title={<strong>Update Day Leave</strong>}
 | 
			
		||||
      >
 | 
			
		||||
        <TextInput
 | 
			
		||||
          mb={'md'}
 | 
			
		||||
          value={customAddNotes.totalLeave}
 | 
			
		||||
          onChange={(e) => {
 | 
			
		||||
            const value = e.target.value
 | 
			
		||||
            if (value) {
 | 
			
		||||
              const floatValue = parseFloat(value)
 | 
			
		||||
              if (
 | 
			
		||||
                /^\d*\.?\d?$/.test(value) &&
 | 
			
		||||
                floatValue >= 0 &&
 | 
			
		||||
                floatValue <= 20
 | 
			
		||||
              ) {
 | 
			
		||||
                setCustomAddNotes({
 | 
			
		||||
                  ...customAddNotes,
 | 
			
		||||
                  totalLeave: value,
 | 
			
		||||
                })
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              setCustomAddNotes({
 | 
			
		||||
                ...customAddNotes,
 | 
			
		||||
                totalLeave: value,
 | 
			
		||||
              })
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
          label={'Total Leave'}
 | 
			
		||||
          placeholder="Input placeholder"
 | 
			
		||||
        />
 | 
			
		||||
        <TextInput
 | 
			
		||||
          mb={'md'}
 | 
			
		||||
          value={customAddNotes.dayAdditional}
 | 
			
		||||
          onChange={(e) => {
 | 
			
		||||
            const value = e.target.value
 | 
			
		||||
            if (value) {
 | 
			
		||||
              const floatValue = parseFloat(value)
 | 
			
		||||
              if (
 | 
			
		||||
                /^\d*\.?\d?$/.test(value) &&
 | 
			
		||||
                floatValue >= 0 &&
 | 
			
		||||
                floatValue <= 20
 | 
			
		||||
              ) {
 | 
			
		||||
                setCustomAddNotes({
 | 
			
		||||
                  ...customAddNotes,
 | 
			
		||||
                  dayAdditional: value,
 | 
			
		||||
                })
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              setCustomAddNotes({
 | 
			
		||||
                ...customAddNotes,
 | 
			
		||||
                dayAdditional: '',
 | 
			
		||||
              })
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
          label={'Day additional leave'}
 | 
			
		||||
          placeholder="Input placeholder"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <Textarea
 | 
			
		||||
          mb={'md'}
 | 
			
		||||
          label="Note"
 | 
			
		||||
          value={customAddNotes.note}
 | 
			
		||||
          onChange={(e) => {
 | 
			
		||||
            setCustomAddNotes({ ...customAddNotes, note: e.target.value })
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
          onClick={() => {
 | 
			
		||||
            setDisableBtn(true)
 | 
			
		||||
            if (
 | 
			
		||||
              customAddNotes.id === 0 ||
 | 
			
		||||
              customAddNotes.totalLeave === '' ||
 | 
			
		||||
              customAddNotes.totalLeave === '0'
 | 
			
		||||
              // customAddNotes.dayAdditional === 0 ||
 | 
			
		||||
              // customAddNotes.note === ''
 | 
			
		||||
            ) {
 | 
			
		||||
              notifications.show({
 | 
			
		||||
                title: 'Error',
 | 
			
		||||
                message: 'Input data required',
 | 
			
		||||
                color: 'red',
 | 
			
		||||
              })
 | 
			
		||||
              setDisableBtn(false)
 | 
			
		||||
            } else {
 | 
			
		||||
              updateInfoNote(
 | 
			
		||||
                customAddNotes.id,
 | 
			
		||||
                customAddNotes.user,
 | 
			
		||||
                customAddNotes.totalLeave,
 | 
			
		||||
                customAddNotes.dayAdditional,
 | 
			
		||||
                customAddNotes.note,
 | 
			
		||||
              )
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
          disabled={disableBtn}
 | 
			
		||||
        >
 | 
			
		||||
          Save
 | 
			
		||||
        </Button>
 | 
			
		||||
      </Drawer>
 | 
			
		||||
      <Box display={'flex'}>
 | 
			
		||||
        <Box style={{ display: 'flex', flexFlow: 'column' }} w={'30%'}>
 | 
			
		||||
          <Box w="100%" display={'flex'}>
 | 
			
		||||
            <Select
 | 
			
		||||
              w="50%"
 | 
			
		||||
              value={date.year}
 | 
			
		||||
              size="xs"
 | 
			
		||||
              ml={'sm'}
 | 
			
		||||
              label="Year"
 | 
			
		||||
              data={Array.from({ length: 10 }, (_, index) => {
 | 
			
		||||
                return {
 | 
			
		||||
                  value: (
 | 
			
		||||
                    parseInt(moment(Date.now()).format('YYYY')) -
 | 
			
		||||
                    3 +
 | 
			
		||||
                    index
 | 
			
		||||
                  ).toString(),
 | 
			
		||||
                  label: (
 | 
			
		||||
                    parseInt(moment(Date.now()).format('YYYY')) -
 | 
			
		||||
                    3 +
 | 
			
		||||
                    index
 | 
			
		||||
                  ).toString(),
 | 
			
		||||
                  disabled:
 | 
			
		||||
                    parseInt(moment(Date.now()).format('YYYY')) - 3 + index >
 | 
			
		||||
                    parseInt(moment(Date.now()).format('YYYY')),
 | 
			
		||||
                }
 | 
			
		||||
              })}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setDate({ ...date, year: e! })
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
          </Box>
 | 
			
		||||
        </Box>
 | 
			
		||||
        <Box
 | 
			
		||||
          w="70%"
 | 
			
		||||
          pl={200}
 | 
			
		||||
          style={{
 | 
			
		||||
            display: 'flex',
 | 
			
		||||
            // alignItems: 'end',
 | 
			
		||||
            justifyContent: 'end',
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          <Box display={'flex'} style={{ alignItems: 'end' }}>
 | 
			
		||||
            <Tooltip label="Save working days">
 | 
			
		||||
              <Button
 | 
			
		||||
                size="xs"
 | 
			
		||||
                ml={'sm'}
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  //form add user new
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                Add
 | 
			
		||||
              </Button>
 | 
			
		||||
            </Tooltip>
 | 
			
		||||
          </Box>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </Box>
 | 
			
		||||
      <Box>
 | 
			
		||||
        <Table
 | 
			
		||||
          striped
 | 
			
		||||
          highlightOnHover
 | 
			
		||||
          withTableBorder
 | 
			
		||||
          withColumnBorders
 | 
			
		||||
          mt={'md'}
 | 
			
		||||
        >
 | 
			
		||||
          <Table.Thead>
 | 
			
		||||
            <Table.Tr bg={'#228be66b'}>
 | 
			
		||||
              <Table.Th></Table.Th>
 | 
			
		||||
              <Table.Th>User</Table.Th>
 | 
			
		||||
              {monthInYear.map((d) => {
 | 
			
		||||
                return (
 | 
			
		||||
                  <Menu width={200} shadow="md" key={d.value}>
 | 
			
		||||
                    <Menu.Target>
 | 
			
		||||
                      <Table.Th ta={'center'} style={{ cursor: 'pointer' }}>
 | 
			
		||||
                        <span>{d.name}</span>
 | 
			
		||||
                      </Table.Th>
 | 
			
		||||
                    </Menu.Target>
 | 
			
		||||
                  </Menu>
 | 
			
		||||
                )
 | 
			
		||||
              })}
 | 
			
		||||
              <Table.Th ta={'center'}>Total Leave</Table.Th>
 | 
			
		||||
              <Table.Th ta={'center'}>Day Off</Table.Th>
 | 
			
		||||
              <Table.Th ta={'center'}>Remaining</Table.Th>
 | 
			
		||||
              <Table.Th ta={'center'}>Notes</Table.Th>
 | 
			
		||||
              <Table.Th ta={'center'}></Table.Th>
 | 
			
		||||
            </Table.Tr>
 | 
			
		||||
          </Table.Thead>
 | 
			
		||||
          <Table.Tbody>
 | 
			
		||||
            {data.map((user, index) => {
 | 
			
		||||
              let totalDayOff = 0
 | 
			
		||||
              let totalDayLeave =
 | 
			
		||||
                user.leaveDay.ld_day + user.leaveDay.ld_date_additional
 | 
			
		||||
              let ld_note = user.leaveDay.ld_note
 | 
			
		||||
              return (
 | 
			
		||||
                <Table.Tr key={user.user.id} className={classes.tableTr}>
 | 
			
		||||
                  <Table.Td ta={'center'}>{index + 1}</Table.Td>
 | 
			
		||||
                  <Table.Td>
 | 
			
		||||
                    <Tooltip multiline label={user.user.name}>
 | 
			
		||||
                      <div>{user.user.name}</div>
 | 
			
		||||
                    </Tooltip>
 | 
			
		||||
                  </Table.Td>
 | 
			
		||||
 | 
			
		||||
                  {monthInYear.map((d, i) => {
 | 
			
		||||
                    let total =
 | 
			
		||||
                      user.monthlyLeaveDays.find((item) => {
 | 
			
		||||
                        return item.month == d.value
 | 
			
		||||
                      })?.leave_days ?? 0
 | 
			
		||||
                    totalDayOff = totalDayOff + total
 | 
			
		||||
                    return (
 | 
			
		||||
                      <Table.Td key={i} ta={'center'}>
 | 
			
		||||
                        {total === 0 ? '' : total}
 | 
			
		||||
                      </Table.Td>
 | 
			
		||||
                    )
 | 
			
		||||
                  })}
 | 
			
		||||
 | 
			
		||||
                  <Table.Td ta={'center'}>{totalDayLeave}</Table.Td>
 | 
			
		||||
                  <Table.Td ta={'center'}>{totalDayOff}</Table.Td>
 | 
			
		||||
                  <Table.Td ta={'center'}>
 | 
			
		||||
                    {totalDayLeave - totalDayOff}
 | 
			
		||||
                  </Table.Td>
 | 
			
		||||
                  <Table.Td>{ld_note}</Table.Td>
 | 
			
		||||
                  <Table.Td ta={'center'}>
 | 
			
		||||
                    <IconEdit
 | 
			
		||||
                      color="green"
 | 
			
		||||
                      onClick={() => {
 | 
			
		||||
                        let totalLeave =
 | 
			
		||||
                          user.leaveDay.ld_day == 0
 | 
			
		||||
                            ? ''
 | 
			
		||||
                            : String(user.leaveDay.ld_day)
 | 
			
		||||
                        let dayAdditional =
 | 
			
		||||
                          user.leaveDay.ld_date_additional == 0
 | 
			
		||||
                            ? ''
 | 
			
		||||
                            : String(user.leaveDay.ld_date_additional)
 | 
			
		||||
                        open1()
 | 
			
		||||
                        setCustomAddNotes({
 | 
			
		||||
                          ...customAddNotes,
 | 
			
		||||
                          id: user.leaveDay.id,
 | 
			
		||||
                          note: ld_note,
 | 
			
		||||
                          totalLeave: totalLeave,
 | 
			
		||||
                          dayAdditional: dayAdditional,
 | 
			
		||||
                          user: {
 | 
			
		||||
                            id: user.user.id,
 | 
			
		||||
                            name: user.user.name,
 | 
			
		||||
                          },
 | 
			
		||||
                        })
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
                  </Table.Td>
 | 
			
		||||
                </Table.Tr>
 | 
			
		||||
              )
 | 
			
		||||
            })}
 | 
			
		||||
          </Table.Tbody>
 | 
			
		||||
        </Table>
 | 
			
		||||
      </Box>
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default LeaveManagement
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import CustomTheme from '@/pages/CustomTheme/CustomTheme'
 | 
			
		|||
import Dashboard from '@/pages/Dashboard/Dashboard'
 | 
			
		||||
import GeneralSetting from '@/pages/GeneralSetting/GeneralSetting'
 | 
			
		||||
import Jira from '@/pages/Jira/Jira'
 | 
			
		||||
import LeaveManagement from '@/pages/LeaveManagement/LeaveManagement'
 | 
			
		||||
import PageNotFound from '@/pages/NotFound/NotFound'
 | 
			
		||||
import Timekeeping from '@/pages/Timekeeping/Timekeeping'
 | 
			
		||||
import Tracking from '@/pages/Tracking/Tracking'
 | 
			
		||||
| 
						 | 
				
			
			@ -88,20 +89,20 @@ const mainRoutes = [
 | 
			
		|||
      </ProtectedRoute>
 | 
			
		||||
    ),
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/jira',
 | 
			
		||||
    element: (
 | 
			
		||||
      <ProtectedRoute mode="route">
 | 
			
		||||
        <BasePage
 | 
			
		||||
          main={
 | 
			
		||||
            <>
 | 
			
		||||
              <Jira />
 | 
			
		||||
            </>
 | 
			
		||||
          }
 | 
			
		||||
        ></BasePage>
 | 
			
		||||
      </ProtectedRoute>
 | 
			
		||||
    ),
 | 
			
		||||
  },
 | 
			
		||||
  // {
 | 
			
		||||
  //   path: '/jira',
 | 
			
		||||
  //   element: (
 | 
			
		||||
  //     <ProtectedRoute mode="route">
 | 
			
		||||
  //       <BasePage
 | 
			
		||||
  //         main={
 | 
			
		||||
  //           <>
 | 
			
		||||
  //             <Jira />
 | 
			
		||||
  //           </>
 | 
			
		||||
  //         }
 | 
			
		||||
  //       ></BasePage>
 | 
			
		||||
  //     </ProtectedRoute>
 | 
			
		||||
  //   ),
 | 
			
		||||
  // },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/worklogs',
 | 
			
		||||
    element: (
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +131,20 @@ const mainRoutes = [
 | 
			
		|||
      </ProtectedRoute>
 | 
			
		||||
    ),
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: '/leave-management',
 | 
			
		||||
    element: (
 | 
			
		||||
      <ProtectedRoute mode="route">
 | 
			
		||||
        <BasePage
 | 
			
		||||
          main={
 | 
			
		||||
            <>
 | 
			
		||||
              <LeaveManagement />
 | 
			
		||||
            </>
 | 
			
		||||
          }
 | 
			
		||||
        ></BasePage>
 | 
			
		||||
      </ProtectedRoute>
 | 
			
		||||
    ),
 | 
			
		||||
  },
 | 
			
		||||
  // {
 | 
			
		||||
  //   path: '/packages',
 | 
			
		||||
  //   element: (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue