refactor create, handle ticket
This commit is contained in:
parent
172af363de
commit
1b35f8481b
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
namespace Modules\Admin\app\Http\Controllers;
|
||||
|
||||
use App\Helper\Cache\CurrentMonthTimekeeping;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Mail\ContactMail;
|
||||
use App\Mail\TicketMail;
|
||||
use App\Models\Notes;
|
||||
use App\Traits\AnalyzeData;
|
||||
|
|
@ -22,7 +20,6 @@ use Modules\Admin\app\Models\Ticket;
|
|||
use Modules\Admin\app\Models\Tracking;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\LeaveDays;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Models\Admin as UserModel;
|
||||
|
||||
class TicketController extends Controller
|
||||
|
|
@ -194,7 +191,7 @@ class TicketController extends Controller
|
|||
|
||||
public function createTicket(Request $request)
|
||||
{
|
||||
// Define validation rules
|
||||
// Validate input
|
||||
$rules = [
|
||||
'start_date' => 'required|date',
|
||||
'start_period' => 'required|string',
|
||||
|
|
@ -202,12 +199,9 @@ class TicketController extends Controller
|
|||
'end_period' => 'required|string',
|
||||
'type' => 'required|string',
|
||||
];
|
||||
|
||||
// Validate the request
|
||||
$request->validate($rules);
|
||||
// return $request;
|
||||
|
||||
// Get data from request
|
||||
// Get input data
|
||||
$startDate = $request->input('start_date');
|
||||
$startPeriod = $request->input('start_period');
|
||||
$endDate = $request->input('end_date');
|
||||
|
|
@ -215,42 +209,19 @@ class TicketController extends Controller
|
|||
$type = $request->input('type');
|
||||
$reason = $request->input('reason');
|
||||
$isAccept = $request->input('is_accept') ?? false;
|
||||
$user = auth('admins')->user(); // user create ticket
|
||||
$user = auth('admins')->user();
|
||||
|
||||
$start_date = Carbon::create($startDate)->setTimezone(env('TIME_ZONE'));
|
||||
$end_date = Carbon::create($endDate)->setTimezone(env('TIME_ZONE'));
|
||||
|
||||
// Get mảng ngày nghỉ
|
||||
$dataListPeriod = $this->getAllPeriodNew($start_date, $startPeriod, $end_date, $endPeriod);
|
||||
if (empty($dataListPeriod)) {
|
||||
return AbstractController::ResultError('Không thể tính toán khoảng thời gian nghỉ hợp lệ.');
|
||||
}
|
||||
|
||||
// --- Chỉ kiểm tra ngày phép khi loại là ONLEAVE ---
|
||||
if ($type === 'ONLEAVE' && !$isAccept) {
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái WAITING
|
||||
$ticketsWaiting = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->whereIn('type', ['ONLEAVE'])
|
||||
->get();
|
||||
$dataListPeriodWaiting = [];
|
||||
if ($ticketsWaiting->count() > 0) {
|
||||
foreach ($ticketsWaiting as $ticket) {
|
||||
$dataListPeriodWaiting = array_merge($dataListPeriodWaiting, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
|
||||
$ticketsWaitingWFH = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->whereIn('type', ['WFH'])
|
||||
->get();
|
||||
$dataListPeriodWaitingWFH = [];
|
||||
if ($ticketsWaitingWFH->count() > 0) {
|
||||
foreach ($ticketsWaitingWFH as $ticket) {
|
||||
$dataListPeriodWaitingWFH = array_merge($dataListPeriodWaitingWFH, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái CONFIRMED
|
||||
$ticketsConfirmed = Ticket::where('user_id', $user->id)
|
||||
->where('status', 'CONFIRMED')
|
||||
->whereIn('type', ['ONLEAVE', 'WFH'])
|
||||
// Lấy các ticket của user trong thời gian request
|
||||
$userTickets = Ticket::where('user_id', $user->id)
|
||||
->whereIn('status', ['WAITING', 'CONFIRMED'])
|
||||
->where(function ($query) use ($start_date, $end_date) {
|
||||
$query->where(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 1: start_date nằm trong khoảng
|
||||
|
|
@ -267,69 +238,49 @@ class TicketController extends Controller
|
|||
});
|
||||
})
|
||||
->get();
|
||||
$userTicketListPeriod = [];
|
||||
if ($userTickets->count() > 0) {
|
||||
foreach ($userTickets as $ticket) {
|
||||
$userTicketListPeriod = array_merge($userTicketListPeriod, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
|
||||
$dataListPeriodConfirmed = [];
|
||||
if ($ticketsConfirmed->count() > 0) {
|
||||
foreach ($ticketsConfirmed as $ticket) {
|
||||
$dataListPeriodConfirmed = array_merge($dataListPeriodConfirmed, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
// dd($dataListPeriodConfirmed,$ticketsConfirmed,$start_date->toDateString(),$end_date->toDateString());
|
||||
// Chuyển đổi mảng đa chiều thành mảng chuỗi để có thể so sánh
|
||||
// Kiểm tra ticket tạo có trùng thời gian với các ticket cũ
|
||||
$periodStrings = [];
|
||||
$waitingPeriodStrings = [];
|
||||
$waitingPeriodStringsWFH = [];
|
||||
$confirmedPeriodStrings = [];
|
||||
|
||||
$userTicketPeriodStrings = [];
|
||||
foreach ($dataListPeriod as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$periodStrings[] = $period['date'] . '_S';
|
||||
$periodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$periodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodWaiting as $period) {
|
||||
foreach ($userTicketListPeriod as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$waitingPeriodStrings[] = $period['date'] . '_S';
|
||||
$waitingPeriodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$waitingPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
$userTicketPeriodStrings[] = $period['date'] . '_S';
|
||||
$userTicketPeriodStrings[] = $period['date'] . '_C';
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodWaitingWFH as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$waitingPeriodStringsWFH[] = $period['date'] . '_S';
|
||||
$waitingPeriodStringsWFH[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$waitingPeriodStringsWFH[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
$userTicketPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodConfirmed as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_S';
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
if (count(array_intersect($periodStrings, $userTicketPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket được tạo trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đang chờ duyệt
|
||||
if (count(array_intersect($periodStrings, $waitingPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket đang chờ duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
// Kiểm tra khi type = ONLEAVE (nghỉ phép)
|
||||
if ($type === 'ONLEAVE' && !$isAccept) {
|
||||
// Lấy tickets nghỉ phép đang ở trạng thái WAITING
|
||||
$ticketsWaiting = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->where('type', 'ONLEAVE')
|
||||
->get();
|
||||
$dataListPeriodWaiting = [];
|
||||
if ($ticketsWaiting->count() > 0) {
|
||||
foreach ($ticketsWaiting as $ticket) {
|
||||
$dataListPeriodWaiting = array_merge($dataListPeriodWaiting, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đang chờ duyệt WFH
|
||||
if (count(array_intersect($periodStrings, $waitingPeriodStringsWFH)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket đang chờ duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đã được duyệt
|
||||
if (count(array_intersect($periodStrings, $confirmedPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket được duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
|
||||
// Tạo thông báo về tickets waiting nếu có
|
||||
|
|
@ -365,7 +316,7 @@ class TicketController extends Controller
|
|||
$balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod);
|
||||
}
|
||||
// dd($balanceCheckResult);
|
||||
// Nếu không đủ ngày phép, trả về thông báo và không tạo ticket
|
||||
// Nếu không đủ ngày phép, trả về thông báo và chưa tạo ticket
|
||||
if (!$balanceCheckResult['success']) {
|
||||
$finalMessage = $waitingTicketsMessage;
|
||||
if (!empty($finalMessage)) {
|
||||
|
|
@ -377,89 +328,13 @@ class TicketController extends Controller
|
|||
|
||||
return AbstractController::ResultError("Không thỏa mãn điều kiện ngày phép", $balanceCheckResult);
|
||||
}
|
||||
} else if ($type === 'WFH') {
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái WAITING
|
||||
$ticketsWaiting = Ticket::where('user_id', $user->id)->where('status', 'WAITING')->whereIn('type', ['WFH', 'ONLEAVE'])
|
||||
->get();
|
||||
$dataListPeriodWaiting = [];
|
||||
if ($ticketsWaiting->count() > 0) {
|
||||
foreach ($ticketsWaiting as $ticket) {
|
||||
$dataListPeriodWaiting = array_merge($dataListPeriodWaiting, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
|
||||
// Lấy thông tin tickets nghỉ phép đang ở trạng thái CONFIRMED
|
||||
$ticketsConfirmed = Ticket::where('user_id', $user->id)
|
||||
->where('status', 'CONFIRMED')
|
||||
->whereIn('type', ['ONLEAVE', 'WFH'])
|
||||
->where(function ($query) use ($start_date, $end_date) {
|
||||
$query->where(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 1: start_date nằm trong khoảng
|
||||
$q->whereBetween(DB::raw('DATE(start_date)'), [$start_date->toDateString(), $end_date->toDateString()]);
|
||||
})
|
||||
->orWhere(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 2: end_date nằm trong khoảng
|
||||
$q->whereBetween(DB::raw('DATE(end_date)'), [$start_date->toDateString(), $end_date->toDateString()]);
|
||||
})
|
||||
->orWhere(function ($q) use ($start_date, $end_date) {
|
||||
// Trường hợp 3: Khoảng thời gian được chọn nằm trong khoảng của ticket
|
||||
$q->where(DB::raw('DATE(start_date)'), '<=', $start_date->toDateString())
|
||||
->where(DB::raw('DATE(end_date)'), '>=', $end_date->toDateString());
|
||||
});
|
||||
})
|
||||
->get();
|
||||
|
||||
$dataListPeriodConfirmed = [];
|
||||
if ($ticketsConfirmed->count() > 0) {
|
||||
foreach ($ticketsConfirmed as $ticket) {
|
||||
$dataListPeriodConfirmed = array_merge($dataListPeriodConfirmed, $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period));
|
||||
}
|
||||
}
|
||||
// dd($dataListPeriodConfirmed,$ticketsConfirmed,$start_date->toDateString(),$end_date->toDateString());
|
||||
// Chuyển đổi mảng đa chiều thành mảng chuỗi để có thể so sánh
|
||||
$periodStrings = [];
|
||||
$waitingPeriodStrings = [];
|
||||
$confirmedPeriodStrings = [];
|
||||
|
||||
foreach ($dataListPeriod as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$periodStrings[] = $period['date'] . '_S';
|
||||
$periodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$periodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodConfirmed as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_S';
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$confirmedPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dataListPeriodWaiting as $period) {
|
||||
if ($period['period'] == 'ALL') {
|
||||
$waitingPeriodStrings[] = $period['date'] . '_S';
|
||||
$waitingPeriodStrings[] = $period['date'] . '_C';
|
||||
} else {
|
||||
$waitingPeriodStrings[] = $period['date'] . '_' . $period['period'];
|
||||
}
|
||||
}
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đang chờ duyệt
|
||||
if (count(array_intersect($periodStrings, $waitingPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket đang chờ duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
|
||||
// Kiểm tra xem có sự trùng lặp giữa request mới và tickets đã được duyệt
|
||||
if (count(array_intersect($periodStrings, $confirmedPeriodStrings)) > 0) {
|
||||
return AbstractController::ResultError('Đã có ticket được duyệt trong thời gian này, không thể tạo ticket mới!');
|
||||
}
|
||||
}
|
||||
// --- Kết thúc kiểm tra ---
|
||||
|
||||
// Nếu đủ ngày phép (hoặc loại ticket không phải ONLEAVE), tiếp tục tạo ticket
|
||||
// Tạo ticket mới khi:
|
||||
// - Ticket được tạo không trùng ngày
|
||||
// - User có đủ phép
|
||||
// - User không đủ phép nhưng vẫn đồng ý tạo
|
||||
$ticket = Ticket::create([
|
||||
'start_date' => $start_date->toDateString(),
|
||||
'start_period' => $startPeriod,
|
||||
|
|
@ -495,7 +370,7 @@ class TicketController extends Controller
|
|||
);
|
||||
// Thêm kiểm tra null trước khi gửi mail
|
||||
if ($dataMasterStartPeriod && $dataMasterEndPeriod && $dataMasterType) {
|
||||
Mail::to($value->email)->send(new TicketMail($data));
|
||||
Mail::to($value->email)->queue(new TicketMail($data));
|
||||
} else {
|
||||
Log::error("Missing category data for ticket ID: {$ticket->id}. Mail not sent.");
|
||||
}
|
||||
|
|
@ -837,11 +712,9 @@ class TicketController extends Controller
|
|||
|
||||
public function handleTicket(Request $request)
|
||||
{
|
||||
|
||||
$rules = [
|
||||
'ticket_id' => 'required',
|
||||
'action' => 'required',
|
||||
// 'admin_note' => 'required'
|
||||
];
|
||||
|
||||
// Validate the request
|
||||
|
|
@ -856,21 +729,6 @@ class TicketController extends Controller
|
|||
if (!$ticket || $ticket->status !== "WAITING") {
|
||||
return response()->json(['message' => "Ticket not found", 'status' => false]);
|
||||
}
|
||||
// Confirm
|
||||
// Update updated_by and admin_note in tickets table
|
||||
// Refuse
|
||||
// Update updated_by and admin_note in tickets table
|
||||
|
||||
// Send notification email to users
|
||||
$startDate = $ticket->start_date; //Start day
|
||||
$startPeriod = $ticket->start_period; //The session begins
|
||||
$endDate = $ticket->end_date; //End date
|
||||
$endPeriod = $ticket->end_period; //Session ends
|
||||
$type = $ticket->type;
|
||||
|
||||
$dataMasterStartPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $startPeriod);
|
||||
$dataMasterEndPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $endPeriod);
|
||||
$dataMasterType = CategoryController::getListMasterByCodeAndType("REASON", $type);
|
||||
|
||||
$dataMasterTypeNotes = CategoryController::getListMasterByType("REASON_NOTES");
|
||||
$onleave = null;
|
||||
|
|
@ -882,16 +740,91 @@ class TicketController extends Controller
|
|||
$leaveWithoutPay = optional($dataMasterTypeNotes->where('c_code', 'LEAVE_WITHOUT_PAY')->first())->c_code;
|
||||
}
|
||||
|
||||
$formattedStartDate = Carbon::createFromFormat('Y-m-d', $startDate)->format('d/m/Y');
|
||||
$formattedEndDate = Carbon::createFromFormat('Y-m-d', $endDate)->format('d/m/Y');
|
||||
|
||||
$user = Admin::find($ticket->user_id);
|
||||
|
||||
if ($onleave == null || $leaveWithoutPay == null) {
|
||||
return response()->json(['message' => "Data reason notes not found", 'status' => false]);
|
||||
}
|
||||
|
||||
if ($action == "confirm") {
|
||||
$this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay);
|
||||
return response()->json(['message' => "confirmed", 'status' => true]);
|
||||
}
|
||||
|
||||
if ($action == "refuse") {
|
||||
$this->handleRefuseTicket($ticket, $admin, $admin_note);
|
||||
return response()->json(['message' => "refused", 'status' => true]);
|
||||
}
|
||||
|
||||
return response()->json(['message' => "failed", 'status' => false]);
|
||||
}
|
||||
|
||||
public function handleTicketEmail(Request $request)
|
||||
{
|
||||
$rules = [
|
||||
'ticket_id' => 'required',
|
||||
'action' => 'required',
|
||||
'admin_email' => 'required' // Need Admin Email
|
||||
];
|
||||
|
||||
// Validate the request
|
||||
$request->validate($rules);
|
||||
|
||||
$ticket_id = $request->input('ticket_id');
|
||||
$admin_note = $request->input('admin_note');
|
||||
$admin_email = $request->input('admin_email');
|
||||
$action = $request->input('action'); // 'confirm' or 'refuse'
|
||||
$admin = Admin::where('email', $admin_email)->first(); // Get admin by email not token
|
||||
$ticket = Ticket::find($ticket_id);
|
||||
|
||||
if (!$ticket || $ticket->status !== "WAITING") {
|
||||
// No ticket found or already confirmed or refused
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
$dataMasterTypeNotes = CategoryController::getListMasterByType("REASON_NOTES");
|
||||
$onleave = null;
|
||||
$leaveWithoutPay = 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;
|
||||
}
|
||||
|
||||
if ($onleave == null || $leaveWithoutPay == null) {
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
if ($action == "confirm") {
|
||||
$this->handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay);
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
if ($action == "refuse") {
|
||||
$this->handleRefuseTicket($ticket, $admin, $admin_note);
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
// Failed
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
private function handleConfirmTicket($ticket, $admin, $admin_note, $onleave, $leaveWithoutPay)
|
||||
{
|
||||
$startDate = $ticket->start_date; //Start day
|
||||
$startPeriod = $ticket->start_period; //The session begins
|
||||
$endDate = $ticket->end_date; //End date
|
||||
$endPeriod = $ticket->end_period; //Session ends
|
||||
$type = $ticket->type;
|
||||
|
||||
$dataMasterStartPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $startPeriod);
|
||||
$dataMasterEndPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $endPeriod);
|
||||
$dataMasterType = CategoryController::getListMasterByCodeAndType("REASON", $type);
|
||||
|
||||
$formattedStartDate = Carbon::createFromFormat('Y-m-d', $startDate)->format('d/m/Y');
|
||||
$formattedEndDate = Carbon::createFromFormat('Y-m-d', $endDate)->format('d/m/Y');
|
||||
|
||||
$user = Admin::find($ticket->user_id);
|
||||
|
||||
if ($ticket->type == "ONLEAVE") {
|
||||
$dataListPeriod = $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||
$balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod, null, true);
|
||||
|
|
@ -1090,62 +1023,10 @@ class TicketController extends Controller
|
|||
"subject" => "[Ticket response] Ticket From " . $admin->name
|
||||
);
|
||||
Mail::to($user->email)->send(new TicketMail($data));
|
||||
|
||||
return response()->json(['message' => "confirmed", 'status' => true]);
|
||||
}
|
||||
|
||||
if ($action == "refuse") {
|
||||
$ticket['updated_by'] = $admin->name;
|
||||
$ticket['admin_note'] = $admin_note;
|
||||
$ticket['status'] = 'REFUSED';
|
||||
$ticket->save();
|
||||
|
||||
$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" => $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));
|
||||
return response()->json(['message' => "refused", 'status' => true]);
|
||||
}
|
||||
|
||||
return response()->json(['message' => "failed", 'status' => false]);
|
||||
}
|
||||
|
||||
// Handle Logic same as HandleTicket, but need email to identify admin and redirect to Management page
|
||||
public function handleTicketEmail(Request $request)
|
||||
private function handleRefuseTicket($ticket, $admin, $admin_note)
|
||||
{
|
||||
|
||||
$rules = [
|
||||
'ticket_id' => 'required',
|
||||
'action' => 'required',
|
||||
'admin_email' => 'required' // Need Admin Email
|
||||
];
|
||||
|
||||
// Validate the request
|
||||
$request->validate($rules);
|
||||
|
||||
$ticket_id = $request->input('ticket_id');
|
||||
$admin_note = $request->input('admin_note');
|
||||
$admin_email = $request->input('admin_email');
|
||||
$action = $request->input('action'); // 'confirm' or 'refuse'
|
||||
$admin = Admin::where('email', $admin_email)->first(); // Get admin by email not token
|
||||
$ticket = Ticket::find($ticket_id);
|
||||
|
||||
if (!$ticket || $ticket->status !== "WAITING") {
|
||||
// No ticket found or already confirmed or refused
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
// Send notification email to users
|
||||
$startDate = $ticket->start_date; //Start day
|
||||
$startPeriod = $ticket->start_period; //The session begins
|
||||
$endDate = $ticket->end_date; //End date
|
||||
|
|
@ -1156,233 +1037,11 @@ class TicketController extends Controller
|
|||
$dataMasterEndPeriod = CategoryController::getListMasterByCodeAndType("TIME_TYPE", $endPeriod);
|
||||
$dataMasterType = CategoryController::getListMasterByCodeAndType("REASON", $type);
|
||||
|
||||
$dataMasterTypeNotes = CategoryController::getListMasterByType("REASON_NOTES");
|
||||
$onleave = null;
|
||||
$leaveWithoutPay = 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;
|
||||
}
|
||||
|
||||
$formattedStartDate = Carbon::createFromFormat('Y-m-d', $startDate)->format('d/m/Y');
|
||||
$formattedEndDate = Carbon::createFromFormat('Y-m-d', $endDate)->format('d/m/Y');
|
||||
|
||||
$user = Admin::find($ticket->user_id);
|
||||
|
||||
if ($onleave == null || $leaveWithoutPay == null) {
|
||||
// Data reason notes not found
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
if ($action == "confirm") {
|
||||
if ($ticket->type == "ONLEAVE") {
|
||||
$dataListPeriod = $this->getAllPeriodNew($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||
$balanceCheckResult = $this->checkLeaveBalance($user, $dataListPeriod);
|
||||
// dd($balanceCheckResult,$dataListPeriod);
|
||||
if ($balanceCheckResult['success'] == false) {
|
||||
if ($balanceCheckResult['months_info']) {
|
||||
foreach ($balanceCheckResult['months_info'] as $monthInfo) {
|
||||
// Lọc các ngày thuộc đúng tháng/năm này
|
||||
$daysInMonth = array_filter($dataListPeriod, function ($item) use ($monthInfo) {
|
||||
$date = \Carbon\Carbon::parse($item['date']);
|
||||
return $date->year == $monthInfo['year'] && $date->month == $monthInfo['month'];
|
||||
});
|
||||
|
||||
$daysWillUse = $monthInfo['days_will_use'] ?? 0;
|
||||
$daysWillUseWithoutPay = $monthInfo['days_will_use_without_pay'] ?? 0;
|
||||
// dd($daysWillUse,$daysWillUseWithoutPay,$daysInMonth);
|
||||
foreach ($daysInMonth as $item) {
|
||||
list($year, $month, $day) = explode('-', $item['date']);
|
||||
$period = $item['period'];
|
||||
$value = ($period === 'ALL') ? 1.0 : 0.5;
|
||||
|
||||
if ($period === 'ALL' && $daysWillUse == 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' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => 'S',
|
||||
'n_reason' => $onleave,
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
Notes::create([
|
||||
'n_user_id' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => 'C',
|
||||
'n_reason' => $leaveWithoutPay,
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
$daysWillUse = 0;
|
||||
$daysWillUseWithoutPay -= 0.5;
|
||||
} elseif ($daysWillUse > 0) {
|
||||
// Dùng ngày phép trước
|
||||
$use = min($daysWillUse, $value);
|
||||
Notes::create([
|
||||
'n_user_id' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => $period,
|
||||
'n_reason' => $onleave,
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
$daysWillUse -= $use;
|
||||
} elseif ($daysWillUseWithoutPay > 0) {
|
||||
// Hết phép, chuyển sang không phép
|
||||
$use = min($daysWillUseWithoutPay, $value);
|
||||
Notes::create([
|
||||
'n_user_id' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => $period,
|
||||
'n_reason' => $leaveWithoutPay,
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
$daysWillUseWithoutPay -= $use;
|
||||
}
|
||||
// Nếu cả hai đều hết thì thôi, không tạo nữa
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Đủ phép
|
||||
foreach ($dataListPeriod as $result) {
|
||||
list($year, $month, $day) = explode('-', $result['date']);
|
||||
Notes::create([
|
||||
'n_user_id' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => $result['period'],
|
||||
'n_reason' => $onleave, // có phép
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$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 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})");
|
||||
|
||||
// Cập nhật cột ld_day_total với số ngày đã làm tròn
|
||||
if ($roundedExcessDays > 0) {
|
||||
$leaveDaysInfo->ld_day_total += $roundedExcessDays;
|
||||
$leaveDaysInfo->save();
|
||||
|
||||
Log::info("Updated leave days for User ID: {$ticket->user_id}. Added {$roundedExcessDays} days (rounded from {$excessDays})");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($ticket->type == "WFH") {
|
||||
$dataListPeriod = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period);
|
||||
foreach ($dataListPeriod as $result) {
|
||||
list($year, $month, $day) = explode('-', $result['date']);
|
||||
Notes::create([
|
||||
'n_user_id' => $ticket->user_id,
|
||||
'n_day' => $day,
|
||||
'n_month' => $month,
|
||||
'n_year' => $year,
|
||||
'n_time_type' => $result['period'],
|
||||
'n_reason' => $ticket->type,
|
||||
'n_note' => $ticket->reason
|
||||
]);
|
||||
|
||||
|
||||
//WFH - start tracking
|
||||
$type = $result['period'];
|
||||
$date = Carbon::create($year, $month, $day)->setTimezone(env('TIME_ZONE'));
|
||||
|
||||
//Default: ALL
|
||||
$start = $date->copy()->setTime(7, 30, 0);
|
||||
$end = $date->copy()->setTime(17, 0, 0);
|
||||
|
||||
if ($type == 'S') {
|
||||
$end = $date->copy()->setTime(11, 30, 0);
|
||||
} else if ($type == 'C') {
|
||||
$start = $date->copy()->setTime(11, 30, 0);
|
||||
}
|
||||
|
||||
Tracking::insert([
|
||||
[
|
||||
'name' => $user->name,
|
||||
'user_id' => $user->id,
|
||||
'status' => 'check in',
|
||||
'time_string' => $start->format('Y-m-d H:i:s'),
|
||||
'created_at' => $start->setTimezone('UTC')
|
||||
],
|
||||
[
|
||||
'name' => $user->name,
|
||||
'user_id' => $user->id,
|
||||
'status' => 'check out',
|
||||
'time_string' => $end->format('Y-m-d H:i:s'),
|
||||
'created_at' => $end->setTimezone('UTC')
|
||||
]
|
||||
]);
|
||||
//WFH - end tracking
|
||||
}
|
||||
}
|
||||
|
||||
$ticket['updated_by'] = $admin->name;
|
||||
$ticket['admin_note'] = $admin_note;
|
||||
$ticket['status'] = 'CONFIRMED';
|
||||
$ticket->save();
|
||||
|
||||
$this->createOrUpdateRecordForCurrentMonth($month, $year);
|
||||
|
||||
// Send notification email to users
|
||||
$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" => $admin_note,
|
||||
"link" => "/tickets", //link đến page admin
|
||||
"status" => "confirmed",
|
||||
"subject" => "[Ticket response] Ticket From " . $admin->name
|
||||
);
|
||||
Mail::to($user->email)->send(new TicketMail($data));
|
||||
|
||||
// Confirm Success
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
if ($action == "refuse") {
|
||||
$ticket['updated_by'] = $admin->name;
|
||||
$ticket['admin_note'] = $admin_note;
|
||||
$ticket['status'] = 'REFUSED';
|
||||
|
|
@ -1402,13 +1061,6 @@ class TicketController extends Controller
|
|||
"subject" => "[Ticket response] Ticket From " . $admin->name
|
||||
);
|
||||
Mail::to($user->email)->send(new TicketMail($data));
|
||||
|
||||
// Refuse Success
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
// Failed
|
||||
return redirect()->to(config('app.client_url') . '/tickets-management');
|
||||
}
|
||||
|
||||
private function getAllPeriodNew($startDate, $startPeriod, $endDate, $endPeriod)
|
||||
|
|
|
|||
Loading…
Reference in New Issue