From 705e8f9216048a653cb9430619edb88c4e130f61 Mon Sep 17 00:00:00 2001 From: dbdbd9 Date: Mon, 30 Jun 2025 14:58:06 +0700 Subject: [PATCH] adjust UI, add send mail when delete note/update refuse ticket --- .../app/Http/Controllers/TicketController.php | 28 ++++++++++++++- .../Controllers/TimekeepingController.php | 30 ++++++++++++++-- .../app/Http/Controllers/UserController.php | 1 + ...add_onleave_permanent_categories_table.php | 35 ------------------- ..._permanent_temporary_categories_table.php} | 12 ++++++- .../pages/LeaveManagement/LeaveManagement.tsx | 2 +- .../src/pages/Timekeeping/Timekeeping.tsx | 10 +++++- 7 files changed, 77 insertions(+), 41 deletions(-) delete mode 100644 BACKEND/database/migrations/2025_06_24_025714_add_onleave_permanent_categories_table.php rename BACKEND/database/migrations/{2025_06_27_025714_add_onleave_future_categories_table.php => 2025_06_30_025714_add_onleave_permanent_temporary_categories_table.php} (62%) diff --git a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php index 2e54764..2df8e81 100644 --- a/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php +++ b/BACKEND/Modules/Admin/app/Http/Controllers/TicketController.php @@ -397,6 +397,31 @@ class TicketController extends Controller // Delete related note, if status change to Refuse if ($request->status == "REFUSED") { $ticket->status = "REFUSED"; + + // Handle send mail + $dataMasterStartPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $ticket->start_period); + $dataMasterEndPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $ticket->end_period); + $dataMasterType = CategoryController::getListMasterByCodeAndType("REASON", $ticket->type); + $formattedStartDate = Carbon::createFromFormat('Y-m-d', $ticket->start_date)->format('d/m/Y'); + $formattedEndDate = Carbon::createFromFormat('Y-m-d', $ticket->end_date)->format('d/m/Y'); + + $user = Admin::find($ticket->user_id); + + $data = array( + "email_template" => "email.notification_tickets_user", + "user_name" => $user->name, + "email" => $user->email, + "name" => $admin->name, //name admin duyệt + "date" => $dataMasterStartPeriod->c_name . " (" . $formattedStartDate . ") - " . $dataMasterEndPeriod->c_name . " (" . $formattedEndDate . ")", + "type" => $dataMasterType->c_name, + "note" => $ticket->reason, + "admin_note" => $ticket->admin_note, + "link" => "/tickets", //link đến page admin + "status" => "refused", + "subject" => "[Ticket response] Ticket From " . $admin->name + ); + Mail::to($user->email)->send(new TicketMail($data)); + Notes::where('ticket_id', $ticket->id)->delete(); } @@ -404,9 +429,10 @@ class TicketController extends Controller $ticket->admin_note = $request->admin_note; // Clear Timekeeping cache + $ticket->save(); + $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!"); } diff --git a/BACKEND/Modules/Admin/app/Http/Controllers/TimekeepingController.php b/BACKEND/Modules/Admin/app/Http/Controllers/TimekeepingController.php index fe2e1f7..f0a046c 100644 --- a/BACKEND/Modules/Admin/app/Http/Controllers/TimekeepingController.php +++ b/BACKEND/Modules/Admin/app/Http/Controllers/TimekeepingController.php @@ -11,7 +11,8 @@ use App\Traits\HasOrderByRequest; use App\Traits\HasSearchRequest; use Carbon\Carbon; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Mail; +use App\Mail\TicketMail; use Modules\Admin\app\Models\Admin; use Modules\Admin\app\Models\MonthlyTimekeeping; use Modules\Admin\app\Models\Tracking; @@ -184,10 +185,35 @@ class TimekeepingController extends Controller } $admin = auth('admins')->user(); + + // Handle send mail + $dataMasterStartPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $ticket->start_period); + $dataMasterEndPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $ticket->end_period); + $dataMasterType = CategoryController::getListMasterByCodeAndType("REASON", $ticket->type); + $formattedStartDate = Carbon::createFromFormat('Y-m-d', $ticket->start_date)->format('d/m/Y'); + $formattedEndDate = Carbon::createFromFormat('Y-m-d', $ticket->end_date)->format('d/m/Y'); + + $user = Admin::find($ticket->user_id); + + $data = array( + "email_template" => "email.notification_tickets_user", + "user_name" => $user->name, + "email" => $user->email, + "name" => $admin->name, //name admin duyệt + "date" => $dataMasterStartPeriod->c_name . " (" . $formattedStartDate . ") - " . $dataMasterEndPeriod->c_name . " (" . $formattedEndDate . ")", + "type" => $dataMasterType->c_name, + "note" => $ticket->reason, + "admin_note" => $ticket->admin_note, + "link" => "/tickets", //link đến page admin + "status" => "refused", + "subject" => "[Ticket response] Ticket From " . $admin->name + ); + Mail::to($user->email)->send(new TicketMail($data)); + + // Update $ticket->updated_by = $admin->name; $ticket->status = "REFUSED"; $ticket->save(); - Notes::where('ticket_id', $ticket->id)->delete(); // Clear Timekeeping cache diff --git a/BACKEND/Modules/Auth/app/Http/Controllers/UserController.php b/BACKEND/Modules/Auth/app/Http/Controllers/UserController.php index a53752e..ff345da 100755 --- a/BACKEND/Modules/Auth/app/Http/Controllers/UserController.php +++ b/BACKEND/Modules/Auth/app/Http/Controllers/UserController.php @@ -88,6 +88,7 @@ class UserController extends Controller 'created_at' => now(), 'updated_at' => now(), ]); + $this->createOrUpdateRecordForCurrentMonth(Carbon::now()->month, Carbon::now()->year); $user_res = [ 'name' => $user->name, diff --git a/BACKEND/database/migrations/2025_06_24_025714_add_onleave_permanent_categories_table.php b/BACKEND/database/migrations/2025_06_24_025714_add_onleave_permanent_categories_table.php deleted file mode 100644 index 8aaa45f..0000000 --- a/BACKEND/database/migrations/2025_06_24_025714_add_onleave_permanent_categories_table.php +++ /dev/null @@ -1,35 +0,0 @@ -insert([ - [ - 'c_code' => 'PERMANENT', - 'c_name' => 'Phép cộng nhân viên chính thức', - 'c_type' => 'PERMANENT_ONLEAVE', - 'c_value' => 3, - 'c_active' => 1, - 'created_at' => now(), - 'updated_at' => now(), - ], - ]); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - DB::table('categories')->where('c_code', 'PERMANENT')->delete(); - } -}; diff --git a/BACKEND/database/migrations/2025_06_27_025714_add_onleave_future_categories_table.php b/BACKEND/database/migrations/2025_06_30_025714_add_onleave_permanent_temporary_categories_table.php similarity index 62% rename from BACKEND/database/migrations/2025_06_27_025714_add_onleave_future_categories_table.php rename to BACKEND/database/migrations/2025_06_30_025714_add_onleave_permanent_temporary_categories_table.php index 69f71fa..968b07d 100644 --- a/BACKEND/database/migrations/2025_06_27_025714_add_onleave_future_categories_table.php +++ b/BACKEND/database/migrations/2025_06_30_025714_add_onleave_permanent_temporary_categories_table.php @@ -13,6 +13,15 @@ return new class extends Migration public function up(): void { DB::table('categories')->insert([ + [ + 'c_code' => 'PERMANENT', + 'c_name' => 'Phép cộng nhân viên chính thức', + 'c_type' => 'PERMANENT_ONLEAVE', + 'c_value' => 1, + 'c_active' => 1, + 'created_at' => now(), + 'updated_at' => now(), + ], [ 'c_code' => 'TEMPORARY_ONLEAVE', 'c_name' => 'Nghỉ dự kiến', @@ -30,6 +39,7 @@ return new class extends Migration */ public function down(): void { - DB::table('categories')->where('c_code', 'TEMPORARY_ONLEAVE')->delete(); + DB::table('categories')->where('c_code', 'PERMANENT')->where('c_type', 'PERMANENT_ONLEAVE')->delete(); + DB::table('categories')->where('c_code', 'TEMPORARY_ONLEAVE')->where('c_type', 'REASON_NOTES')->delete(); } }; diff --git a/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx b/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx index 9f58a4f..86b543e 100644 --- a/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx +++ b/FRONTEND/src/pages/LeaveManagement/LeaveManagement.tsx @@ -711,7 +711,7 @@ const LeaveManagement = () => { return ( 0 ? '#ffb5b5' : ''} - opacity={d.value > currentMonth ? 0.6 : 1} + opacity={d.value > currentMonth ? 0.4 : 1} key={i} ta={'center'} > diff --git a/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx b/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx index fee2b95..e030c08 100644 --- a/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx +++ b/FRONTEND/src/pages/Timekeeping/Timekeeping.tsx @@ -148,6 +148,7 @@ const Timekeeping = () => { const [exportOption, setExportOption] = useState('default') const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false) + const [isDisableDeleteBtn, setIsDisableDeleteBtn] = useState(false) const [noteToDelete, setNoteToDelete] = useState(null) const getListMasterByType = async (type: string) => { @@ -467,7 +468,9 @@ const Timekeeping = () => { const handleConfirmDelete = async () => { if (noteToDelete) { + setIsDisableDeleteBtn(true) await handleDelete(noteToDelete.id) + setIsDisableDeleteBtn(false) setIsDeleteConfirmOpen(false) setNoteToDelete(null) } @@ -506,10 +509,15 @@ const Timekeeping = () => { setIsDeleteConfirmOpen(false) setNoteToDelete(null) }} + disabled={isDisableDeleteBtn} > Cancel -