From edca5306ad1d99f2e598e62ac79c8afdfc5469da Mon Sep 17 00:00:00 2001 From: JoshuaMicallefYBSU <91457812+JoshuaMicallefYBSU@users.noreply.github.com> Date: Mon, 19 Aug 2024 01:57:43 +1000 Subject: [PATCH 1/3] Automatic Training Checks --- .../Controllers/DiscordTestController.php | 4 +- .../Training/ApplicationsController.php | 2 +- .../Training/InstructingController.php | 33 ++-- app/Jobs/DiscordTrainingUpdates.php | 183 ++++++++++++++++++ app/Services/DiscordClient.php | 31 ++- .../instructing/students/student.blade.php | 2 +- resources/views/my/index.blade.php | 4 +- 7 files changed, 237 insertions(+), 22 deletions(-) create mode 100644 app/Jobs/DiscordTrainingUpdates.php diff --git a/app/Http/Controllers/DiscordTestController.php b/app/Http/Controllers/DiscordTestController.php index 66585945..6e442408 100644 --- a/app/Http/Controllers/DiscordTestController.php +++ b/app/Http/Controllers/DiscordTestController.php @@ -4,7 +4,7 @@ use Illuminate\Http\Request; use App\Services\DiscordClient; -use App\Jobs\ProcessShanwickController; +use App\Jobs\DiscordTrainingUpdates; class DiscordTestController extends Controller { @@ -26,7 +26,7 @@ public function EditTagTest() public function Shanwick() { // Dispatch the job - $job = ProcessShanwickController::dispatch(); + $job = DiscordTrainingUpdates::dispatch(); // Call the handle method directly to get the result synchronously $result = $job->handle(); diff --git a/app/Http/Controllers/Training/ApplicationsController.php b/app/Http/Controllers/Training/ApplicationsController.php index 7922eea2..4425e687 100644 --- a/app/Http/Controllers/Training/ApplicationsController.php +++ b/app/Http/Controllers/Training/ApplicationsController.php @@ -144,7 +144,7 @@ public function applyPost(Request $request) $discord = new DiscordClient(); $discord->sendMessageWithEmbed(config('app.env') == 'local' ? intval(config('services.discord.web_logs')) : intval(config('services.discord.applications')), 'New Training Applicant!', $application->user->fullName('FLC').' has just applied to control at Gander Oceanic! - [View their application now](https://ganderoceanic.ca/admin/training/applications/'.$application->reference_id.')'); +[View their application now](https://ganderoceanic.ca/admin/training/applications/'.$application->reference_id.')'); //Redirect to application page return redirect()->route('training.applications.show', $application->reference_id); diff --git a/app/Http/Controllers/Training/InstructingController.php b/app/Http/Controllers/Training/InstructingController.php index 4982d79f..1f7b17b3 100644 --- a/app/Http/Controllers/Training/InstructingController.php +++ b/app/Http/Controllers/Training/InstructingController.php @@ -64,7 +64,7 @@ public function instructors() public function students() { //Get all students - $students = Student::whereCurrent(true)->orderBy('created_at', 'desc')->get(); + $students = Student::whereCurrent(true)->orderBy('created_at', 'asc')->get(); $pastStudents = Student::whereCurrent(false)->orderBy('updated_at', 'desc')->get(); //Return view @@ -600,19 +600,22 @@ public function assignStudentToInstructor(Request $request, $student_id) $link->student_id = $student->id; $link->save(); - //If student has ready for pick up, remove and add In Progress + //Relabelling process foreach ($student->labels as $label) { - //Find label - if (strtolower($label->label()->name) == 'ready for pick-up') { - $label->delete(); + $label->delete(); + } + + //Assign it with link + $link = new StudentStatusLabelLink([ + 'student_id' => $student->id, + 'student_status_label_id' => StudentStatusLabel::whereName('In Progress')->first()->id, + ]); + $link->save(); - //Assign it with link - $link = new StudentStatusLabelLink([ - 'student_id' => $student->id, - 'student_status_label_id' => StudentStatusLabel::whereName('In Progress')->first()->id, - ]); - $link->save(); - } + // Update Thread Tag + if ($student->user->hasDiscord() && $student->user->member_of_czqo) { + $discord = new DiscordClient(); + $discord->EditThreadTag('In Progress', $student->user->id); } //Notify instructor @@ -646,6 +649,12 @@ public function dropStudentFromInstructor($student_id) ]); $link->save(); + // Update Thread Tag + if ($student->user->hasDiscord() && $student->user->member_of_czqo) { + $discord = new DiscordClient(); + $discord->EditThreadTag('Ready For Pick-Up', $student->user->id); + } + //Discord notification in instructors channel $discord = new DiscordClient(); $discord->sendMessageWithEmbed(intval(config('services.discord.instructors')), 'A new student is available for pick-up by an Instructor', $student->user->fullName('FLC').' is available to be picked up by an instructor!'); diff --git a/app/Jobs/DiscordTrainingUpdates.php b/app/Jobs/DiscordTrainingUpdates.php new file mode 100644 index 00000000..a6919091 --- /dev/null +++ b/app/Jobs/DiscordTrainingUpdates.php @@ -0,0 +1,183 @@ +getClient()->get('guilds/'.env('DISCORD_GUILD_ID').'/threads/active'); + $results = json_decode($response->getBody(), true); + + foreach ($results['threads'] as $thread) { + + // Get the ID of the Active Training Thread + if (preg_match('/\d+$/', $thread['name'], $matches)) { + $cid = $matches[0]; + } else { + $cid = null; + } + + // Check Lable is 'In Progress' or 'Ready For Pick-Up' + + // Check Sessions Upcoming + $student = Student::where('user_id', $cid)->first(); + $upcoming_sessions = TrainingSession::where('student_id', $student->id)->whereBetween('scheduled_time', [Carbon::now(), Carbon::now()->addDays(7)])->first(); + + if($upcoming_sessions == null){ + // There is no sessions within the next week + $counter++; //Add 1 to the $counter variable + + // SendEmbed to ask student to send availability + $discord->sendEmbedInTrainingThread($cid, "Your Availability", 'Hello, <@'.$student->user->discord_user_id.'> + +Please provide your availability for the next 7-14 days. Please ensure to tag the `@Instructor` role with all times you are available. Please provide these times in Zulu Format. + +One of our team will make contact with you to organise a session if they have availability matching yours. + +*If you have done this in the past few days, please disregard this message.*'); + } + } + + // Tell the log chat + $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Thread Availability Requests',$counter. ' Training Threads have been messaged asking for their weekly availability. This is only completed if a student has no scheduled session within the next 7 days.'); + } + + // Check 'Awaiting Exam' label students between 31-37 Days after Application + { + $count = 0; + + $student = Student::whereBetween('created_at', [Carbon::now()->subDays(37), Carbon::now()->subDays(30)])->where('current', true)->get(); + + foreach($student as $s){ + if ($s->hasLabel('Awaiting Exam')) { + // Add one to the count + $count++; + // SendEmbed to ask student to send availability + $discord->sendEmbedInTrainingThread($cid, "Exam Not Requested", 'Hello, <@'.$s->user->discord_user_id.'> + +Our records indicate that you have not requested, or completed your exam within a month of your Application being approved. + +Please read the above message in order to understand how to request the exam. + +Should you not request, and pass the exam within 60 days of your application being accepted, your training will be automatically terminated, and you will need to reapply to begin your training once more. + +**Kind Regards, +Gander Oceanic Training Team**'); + } + } + + // Tell the log chat + $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Thread Exam Requests Reminder',$count. ' Students are between 30-37 days past application without completing the exam. They have been notified of this.'); + } + + + // Check 'Awaiting-Exam' label students 60 Days after Application and Terminate Training Automatically + { + $count2 = 0; + + $student = Student::where('created_at', '<=', Carbon::now()->subDays(60))->where('current', true)->get(); + + foreach($student as $s){ + if ($s->hasLabel('Awaiting Exam')) { + // Add one to the count + $count2++; + + // dd($s); + + //Make as not current + $s->current = false; + + //Remove role + $s->user->removeRole('Student'); + + //Discord Updates + if ($s->user->hasDiscord() && $s->user->member_of_czqo) { + //Get Discord client + $discord = new DiscordClient(); + + //remove student discord role + $discord->removeRole($s->user->discord_user_id, 482824058141016075); + + $discord->EditThreadTag('Inactive', $s->user->id); + + //close training Thread + $discord->closeTrainingThread($s->user->id, $s->user->discord_user_id, 'terminate'); + + // Notify Senior Team that new training has been terminated. + $discord->sendMessageWithEmbed(config('app.env') == 'local' ? intval(config('services.discord.web_logs')) : intval(config('services.discord.instructors')), 'Training Terminated', $s->user->fullName('FLC').' has had their training terminated. `Exam not completed within 60 days.`', 'error'); + + } else { + //Get Discord client + $discord = new DiscordClient(); + + // Notify Senior Team that training has been terminated + $discord->sendMessageWithEmbed(config('app.env') == 'local' ? intval(config('services.discord.web_logs')) : intval(config('services.discord.instructors')), 'Training Terminated', $s->user->fullName('FLC').' has had their training terminated. `Exam not completed within 60 days.`', 'error'); + } + + foreach ($s->labels as $label) { + if (!in_array($label->label()->name, ['inactive'])) { + $label->delete(); + } + } + + //Remove labels and instructor links and availability + $label = new StudentStatusLabelLink([ + 'student_status_label_id' => StudentStatusLabel::whereName('Inactive')->first()->id, + 'student_id' => $s->id, + ]); + $label->save(); + + + if ($s->instructor()) { + $s->instructor()->delete(); + } + foreach ($s->availability as $a) { + $a->delete(); + } + + //notify + $s->user->notify(new RemovedAsStudent()); + + //Save + $s->save(); + } + } + + // Tell the log chat + $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Termination',$count2. ' Students have been terminated automatically. Exam not completed within 60 days.'); + + } + } +} diff --git a/app/Services/DiscordClient.php b/app/Services/DiscordClient.php index add3690a..741039a7 100644 --- a/app/Services/DiscordClient.php +++ b/app/Services/DiscordClient.php @@ -22,6 +22,11 @@ public function __construct() ]); } + // Get Discord Client (For external use outside of this php file) + public function getClient() { + return $this->client; + } + public function sendMessage($channelId, $message) { $response = $this->client->post("channels/{$channelId}/messages", [ @@ -132,16 +137,34 @@ public function closeTrainingThread($cid, $discord_id, $status) $this->sendMessageWithEmbed($thread['id'], 'Oceanic Training Completed!', 'Congratulations <@'.$discord_id.'>, you have now been certified on Gander & Shanwick Oceanic! -This training thread will now be closed due to the completion of your training. Your discord roles will automatically be updated within the next 24 Hours. +This training thread will now be closed due to the completion of your training. Your discord roles will automatically be updated within the next 24 If you have any questions, please reach out to your Instructor, or ask your question in <#836707337829089322>. -Enjoy controlling Gander & Shanwick OCA!'); +Enjoy controlling Gander & Shanwick OCA! + +**Kind Regards, +Gander Oceanic Training Team**'); + } elseif($status == "cancel") { $this->sendMessageWithEmbed($thread['id'], 'Oceanic Training Cancelled', -'<@'.$discord_id.'>, Your training request with Gander Oceanic has been terminated on timestamp.':F> +'<@'.$discord_id.'>, Your training request with Gander Oceanic has been terminated at timestamp.':F> + +If you would like to begin training again, please re-apply via the Gander Website. + +**Kind Regards, +Gander Oceanic Training Team**'); + + } elseif($status == "terminate"){ + $this->sendMessageWithEmbed($thread['id'], 'Oceanic Training Terminated', +'<@'.$discord_id.'>, Your training request with Gander Oceanic has been terminated at timestamp.':F>. + +This is due to not completing the Exam within 60 Days of your application being accepted. + +If you would like to begin training again, please re-apply via the Gander Website. -If you would like to begin training again, please re-apply via the Gander Website.'); +**Kind Regards, +Gander Oceanic Training Team**'); } // Lock and Archive the Thread diff --git a/resources/views/admin/training/instructing/students/student.blade.php b/resources/views/admin/training/instructing/students/student.blade.php index 304b438b..f202877f 100644 --- a/resources/views/admin/training/instructing/students/student.blade.php +++ b/resources/views/admin/training/instructing/students/student.blade.php @@ -58,7 +58,7 @@