orderByRequest($tickets, $request); // Filter $this->filterRequest( builder: $tickets, request: $request, filterKeys: [ 'type' => self::F_TEXT, 'reason' => self::F_TEXT, 'updated_by' => self::F_TEXT, 'start_date' => [ 'type' => self::F_THAN_EQ_DATETIME, 'column' => 'tickets.start_date' ], 'end_date' => [ 'type' => self::F_THAN_EQ_DATETIME, 'column' => 'tickets.end_date' ], ] ); $this->searchRequest( builder: $tickets, value: $request->get('search'), fields: [ 'users.name', "start_date", "startPeriod.c_name", "end_date", "endPeriod.c_name", "typeReason.c_name", 'status', "reason", ] ); $responseData = array_merge( $tickets ->join('users', 'tickets.user_id', '=', 'users.id') ->leftJoin("categories as startPeriod", function ($join) { $join->on('start_period', '=', 'startPeriod.c_code'); $join->on('startPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')")); }) ->leftJoin("categories as endPeriod", function ($join) { $join->on('end_period', '=', 'endPeriod.c_code'); $join->on('endPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')")); }) ->leftJoin("categories as typeReason", function ($join) { $join->on('type', '=', 'typeReason.c_code'); $join->on('typeReason.c_type', DB::raw("CONCAT('REASON')")); }) ->leftJoin("categories as statusTickets", function ($join) { $join->on('status', '=', 'statusTickets.c_code'); $join->on('statusTickets.c_type', DB::raw("CONCAT('STATUS_TICKETS')")); }) ->where('user_id', auth('admins')->user()->id)->orderBy('tickets.created_at', 'desc') ->select( 'users.name as user_name', 'users.email', 'tickets.*', 'startPeriod.c_name as startPeriodName', 'endPeriod.c_name as endPeriodName', 'typeReason.c_name as typeReasonName', 'statusTickets.c_name as statusTicketsName', ) ->paginate($request->get('per_page'))->toArray(), ['status' => true] ); return response()->json($responseData); } public function getAll(Request $request) { $tickets = new Ticket; // Order by $this->orderByRequest($tickets, $request); // Filter $this->filterRequest( builder: $tickets, request: $request, filterKeys: [ 'type' => self::F_TEXT, 'reason' => self::F_TEXT, 'updated_by' => self::F_TEXT, 'start_date' => [ 'type' => self::F_THAN_EQ_DATETIME, 'column' => 'tickets.start_date' ], 'end_date' => [ 'type' => self::F_THAN_EQ_DATETIME, 'column' => 'tickets.end_date' ], ] ); $this->searchRequest( builder: $tickets, value: $request->get('search'), fields: [ 'users.name', "start_date", "startPeriod.c_name", "end_date", "endPeriod.c_name", "typeReason.c_name", 'status', "reason", "admin_note" ] ); if ($request->typeReason != '') { $tickets = $tickets->where('tickets.type', '=', $request->typeReason); } if ($request->statusFilter != '') { $tickets = $tickets->where('tickets.status', '=', $request->statusFilter); } $responseData = array_merge( $tickets ->join('users', 'tickets.user_id', '=', 'users.id') ->leftJoin("categories as startPeriod", function ($join) { $join->on('start_period', '=', 'startPeriod.c_code'); $join->on('startPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')")); }) ->leftJoin("categories as endPeriod", function ($join) { $join->on('end_period', '=', 'endPeriod.c_code'); $join->on('endPeriod.c_type', DB::raw("CONCAT('TIME_TYPE')")); }) ->leftJoin("categories as typeReason", function ($join) { $join->on('type', '=', 'typeReason.c_code'); $join->on('typeReason.c_type', DB::raw("CONCAT('REASON')")); }) ->leftJoin("categories as statusTickets", function ($join) { $join->on('status', '=', 'statusTickets.c_code'); $join->on('statusTickets.c_type', DB::raw("CONCAT('STATUS_TICKETS')")); }) ->select( 'users.name as user_name', 'users.email', 'tickets.*', 'startPeriod.c_name as startPeriodName', 'endPeriod.c_name as endPeriodName', 'typeReason.c_name as typeReasonName', 'statusTickets.c_name as statusTicketsName', ) ->orderBy('tickets.created_at', 'desc')->paginate($request->get('per_page'))->toArray(), ['status' => true] ); return response()->json($responseData); } public function createTicket(Request $request) { // Define validation rules $rules = [ 'start_date' => 'required|date', 'start_period' => 'required|string', 'end_date' => 'required|date|after_or_equal:start_date', 'end_period' => 'required|string', 'type' => 'required|string', ]; // Validate the request $request->validate($rules); // return $request; //Get data from request $startDate = $request->input('start_date'); //Start day $startPeriod = $request->input('start_period'); //The session begins $endDate = $request->input('end_date'); //End date $endPeriod = $request->input('end_period'); //Session ends $type = $request->input('type'); $reason = $request->input('reason'); $user = auth('admins')->user(); // user create ticket // return $user; $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 = auth('admins')->user(); $ticket = Ticket::create([ 'start_date' => Carbon::create($startDate)->setTimezone(env('TIME_ZONE')), 'start_period' => $startPeriod, 'end_date' => Carbon::create($endDate)->setTimezone(env('TIME_ZONE')), 'end_period' => $endPeriod, 'type' => $type, 'status' => 'WAITING', 'reason' => $reason, 'user_id' => $user->id ]); // Send notification email to admin (list) $admins = Admin::where('permission', 'like', '%admin%')->get(); foreach ($admins as $key => $value) { $data = array( "email_template" => "email.notification_tickets", "email" => $user->email, "name" => $user->name, "date" => $dataMasterStartPeriod->c_name . " (" . $formattedStartDate . ") - " . $dataMasterEndPeriod->c_name . " (" . $formattedEndDate . ")", "type" => $dataMasterType->c_name, "note" => $reason, "link" => "/tickets-management", //link đến page admin "subject" => "[Ticket request] Ticket From " . $user->name ); Mail::to($value->email)->send(new TicketMail($data)); } return response()->json(['data' => $ticket, 'status' => true]); } public function deleteTicket(Request $request) { $rules = [ 'ticket_id' => 'required' ]; // Validate the request $request->validate($rules); $user = auth('admins')->user(); $ticket_id = $request->input('ticket_id'); $ticket = Ticket::find($ticket_id); if ($ticket) { // $user->id == user_id of ticket ---> delete if ($ticket->user_id == $user->id) { $ticket->delete(); return response()->json(['message' => 'delete success', 'status' => true]); } else { return response()->json(['message' => 'You are committing an act of vandalism', 'status' => false]); } } return response()->json(['message' => 'Delete fail', 'status' => false]); } public function handleTicket(Request $request) { $rules = [ 'ticket_id' => 'required', 'action' => 'required', // 'admin_note' => 'required' ]; // Validate the request $request->validate($rules); $ticket_id = $request->input('ticket_id'); $admin_note = $request->input('admin_note'); $action = $request->input('action'); // 'confirm' or 'refuse' $admin = auth('admins')->user(); $ticket = Ticket::find($ticket_id); if (!$ticket || $ticket->status !== "WAITING") { return response()->json(['message' => "Ticket not found", 'status' => false]); } $results = $this->getAllPeriod($ticket->start_date, $ticket->start_period, $ticket->end_date, $ticket->end_period); // $admin->id != user_id of ticket ---> continue // Confirm // Add records to the notes table like function Timekeeping.addNoteForUser() based on the $results array // Update updated_by and admin_note in tickets table // Send notification email to users // Refuse // Update updated_by and admin_note in tickets table $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 ($action == "confirm") { foreach ($results 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 ]); if ($ticket->type == "WFH") { $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') ] ]); } } $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)); 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]); } private function getAllPeriod($startDate, $startPeriod, $endDate, $endPeriod) { //Create an array to contain the results $results = []; //Use CarbonPeriod to create a period from the start date to the end date $period = CarbonPeriod::create($startDate, $endDate); $time_type = Category::where('c_type', 'TIME_TYPE')->get(); $morning = null; $afternoon = null; $all_day = null; foreach ($time_type as $item) { switch ($item->c_code) { case 'S': $morning = $item; break; case 'C': $afternoon = $item; break; case 'ALL': $all_day = $item; break; } } foreach ($period as $date) { //If it is the start date if ($date->isSameDay($startDate)) { //Add start session //If the start date is morning, add afternoon if ($startDate == $endDate) { if ($startPeriod == $endPeriod) { $results[] = ['date' => $date->toDateString(), 'period' => $startPeriod]; } else { $results[] = ['date' => $date->toDateString(), 'period' => $all_day->c_code]; } } else { if ($startPeriod == $morning->c_code) { $results[] = ['date' => $date->toDateString(), 'period' => $all_day->c_code]; } else { $results[] = ['date' => $date->toDateString(), 'period' => $startPeriod]; } } } elseif ($date->isSameDay($endDate)) { //If it is the end date //If the end session is afternoon, add morning first if ($endPeriod == $afternoon->c_code) { $results[] = ['date' => $date->toDateString(), 'period' => $all_day->c_code]; } else { $results[] = ['date' => $date->toDateString(), 'period' => $endPeriod]; } } else { //Add both sessions for days between intervals $results[] = ['date' => $date->toDateString(), 'period' => $all_day->c_code]; // $results[] = ['date' => $date->toDateString(), 'period' => 'afternoon']; } } //Returns results return $results; } }