From 411cc7fe0369f193da692749583746939d911ca4 Mon Sep 17 00:00:00 2001 From: Sallu9007 Date: Tue, 15 Apr 2025 21:51:26 +0530 Subject: [PATCH] Feat: Mailing system --- .../Controllers/MissingProofsController.php | 313 ++++++++++++++++++ app/Mail/MissingProofsMail.php | 40 +++ app/Models/ActivitiesAttended.php | 5 + database/seeders/DatabaseSeeder.php | 1 + database/seeders/PublicationSeeder.php | 133 ++++++++ .../views/emails/missing-proofs.blade.php | 85 +++++ routes/web.php | 3 + 7 files changed, 580 insertions(+) create mode 100644 app/Http/Controllers/MissingProofsController.php create mode 100644 app/Mail/MissingProofsMail.php create mode 100644 database/seeders/PublicationSeeder.php create mode 100644 resources/views/emails/missing-proofs.blade.php diff --git a/app/Http/Controllers/MissingProofsController.php b/app/Http/Controllers/MissingProofsController.php new file mode 100644 index 0000000..cab5b65 --- /dev/null +++ b/app/Http/Controllers/MissingProofsController.php @@ -0,0 +1,313 @@ +input('categories', []); + + if (empty($selectedCategories)) { + return redirect()->back()->with('error', 'Please select at least one category.'); + } + + // Array to store missing proofs by faculty + $missingProofsByFaculty = []; + + // Check each selected category + foreach ($selectedCategories as $category) { + switch ($category) { + case 'publications': + $this->checkPublications($missingProofsByFaculty); + break; + case 'activities_attended': + $this->checkActivitiesAttended($missingProofsByFaculty); + break; + case 'activities_organised': + $this->checkActivitiesOrganised($missingProofsByFaculty); + break; + case 'iv_organised': + $this->checkIVOrganised($missingProofsByFaculty); + break; + case 'books_published': + $this->checkBooksPublished($missingProofsByFaculty); + break; + case 'external_engagement': + $this->checkExternalEngagement($missingProofsByFaculty); + break; + case 'online_courses': + $this->checkOnlineCourses($missingProofsByFaculty); + break; + case 'patents_copyrights': + $this->checkPatentsCopyrights($missingProofsByFaculty); + break; + } + } + + // Send emails to faculty members + $this->sendMissingProofEmails($missingProofsByFaculty); + + return redirect()->back()->with('success', 'Emails sent successfully to faculty members with missing proofs.'); + } + + private function checkPublications(&$missingProofsByFaculty) + { + // Find publications with missing proofs (paper_file is null) + $missingProofs = Publication::whereNull('paper_file')->get(); + + foreach ($missingProofs as $publication) { + $facultyId = $publication->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Publication', + 'id' => $publication->id, + 'primary_name' => $publication->title, + 'details' => [ + 'Affiliation' => $publication->affiliation, + 'Start Date' => $publication->start_date->format('d-m-Y'), + 'End Date' => $publication->end_date->format('d-m-Y'), + 'First Author' => $publication->first_author_name + ] + ]; + } + } + + private function checkActivitiesAttended(&$missingProofsByFaculty) + { + $missingProofs = ActivitiesAttended::whereNull('proof')->get(); + + foreach ($missingProofs as $activity) { + $facultyId = $activity->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Activity Attended', + 'id' => $activity->id, + 'primary_name' => $activity->title, + 'details' => [ + 'Organising Institute' => $activity->organising_institute, + 'Start Date' => $activity->start_date->format('d-m-Y'), + 'End Date' => $activity->end_date->format('d-m-Y') + ] + ]; + } + } + + private function checkActivitiesOrganised(&$missingProofsByFaculty) + { + $missingProofs = ActivitiesOrganised::whereNull('proof')->get(); + + foreach ($missingProofs as $activity) { + $facultyId = $activity->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Activity Organised', + 'id' => $activity->id, + 'primary_name' => $activity->title, + 'details' => [ + 'Objective' => $activity->objective, + 'Outcomes' => $activity->outcomes, + 'Start Date' => $activity->start_date->format('d-m-Y'), + 'End Date' => $activity->end_date->format('d-m-Y') + ] + ]; + } + } + + private function checkIVOrganised(&$missingProofsByFaculty) + { + $missingProofs = IvOrganised::whereNull('proof')->get(); + + foreach ($missingProofs as $activity) { + $facultyId = $activity->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Industrial Visit Organised', + 'id' => $activity->id, + 'primary_name' => $activity->company_name, + 'details' => [ + 'Company Address' => $activity->company_address, + 'Objective' => $activity->objective, + 'Outcomes' => $activity->outcomes, + 'Start Date' => $activity->start_date->format('d-m-Y'), + 'End Date' => $activity->end_date->format('d-m-Y') + ] + ]; + } + } + + private function checkBooksPublished(&$missingProofsByFaculty) + { + $missingProofs = BooksPublished::whereNull('proof')->get(); + + foreach ($missingProofs as $book) { + $facultyId = $book->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Book Published', + 'id' => $book->id, + 'primary_name' => $book->title, + 'details' => [ + 'Author' => $book->author, + 'Publisher' => $book->publisher, + 'ISSN' => $book->issn, + 'Date Of Publication' => $book->date_of_publication->format('d-m-Y'), + ] + ]; + } + } + + private function checkExternalEngagement(&$missingProofsByFaculty) + { + $missingProofs = ExternalEngagement::whereNull('proof')->get(); + + foreach ($missingProofs as $engagement) { + $facultyId = $engagement->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'External Engagement', + 'id' => $engagement->id, + 'primary_name' => $engagement->activity, + 'details' => [ + 'Activity Description' => $engagement->activity_description, + 'Inviting Organization' => $engagement->inviting_organization, + 'Start Date' => $engagement->start_date->format('d-m-Y'), + 'End Date' => $engagement->end_date->format('d-m-Y') + ] + ]; + } + } + + private function checkOnlineCourses(&$missingProofsByFaculty) + { + $missingProofs = OnlineCourse::whereNull('proof')->get(); + + foreach ($missingProofs as $course) { + $facultyId = $course->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Online Course', + 'id' => $course->id, + 'primary_name' => $course->course, + 'details' => [ + 'Offered By' => $course->offered_by, + 'Publisher' => $course->publisher, + 'Start Date' => $course->start_date->format('d-m-Y'), + 'End Date' => $course->end_date->format('d-m-Y') + ] + ]; + } + } + + private function checkPatentsCopyrights(&$missingProofsByFaculty) + { + $missingProofs = Patent::whereNull('proof')->get(); + + foreach ($missingProofs as $patent) { + $facultyId = $patent->faculty_id; + + if (!isset($missingProofsByFaculty[$facultyId])) { + $missingProofsByFaculty[$facultyId] = [ + 'faculty' => User::find($facultyId), + 'items' => [] + ]; + } + + $missingProofsByFaculty[$facultyId]['items'][] = [ + 'type' => 'Patent/Copyright', + 'id' => $patent->id, + 'primary_name' => $patent->title, + 'details' => [ + 'Investigator' => $patent->investigator, + 'Application No' => $patent->application_no, + 'Status' => $patent->status, + 'Date Of Submission' => $patent->date_of_submission->format('d-m-Y'), + 'Date Of Filling' => $patent->date_of_filling->format('d-m-Y'), + ] + ]; + } + } + + private function sendMissingProofEmails($missingProofsByFaculty) + { + foreach ($missingProofsByFaculty as $facultyData) { + $faculty = $facultyData['faculty']; + $items = $facultyData['items']; + + // Send email + try { + Mail::to($faculty->email)->send(new MissingProofsMail($faculty, $items)); + } catch (\Exception $e) { + // Handle the exception (log or report) + \Log::error('Failed to send email: ' . $e->getMessage()); + // You could flash a message for admin if this is run from an admin panel + } + } + } +} \ No newline at end of file diff --git a/app/Mail/MissingProofsMail.php b/app/Mail/MissingProofsMail.php new file mode 100644 index 0000000..8954481 --- /dev/null +++ b/app/Mail/MissingProofsMail.php @@ -0,0 +1,40 @@ +faculty = $faculty; + $this->items = $items; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + // dd("hehe"); + return $this->subject('Missing Proofs Notification') + ->view('emails.missing-proofs'); + } +} \ No newline at end of file diff --git a/app/Models/ActivitiesAttended.php b/app/Models/ActivitiesAttended.php index 30f5d25..dc3c879 100644 --- a/app/Models/ActivitiesAttended.php +++ b/app/Models/ActivitiesAttended.php @@ -24,6 +24,11 @@ class ActivitiesAttended extends Model 'proof', ]; + protected $casts = [ + 'start_date' => 'datetime', + 'end_date' => 'datetime', + ]; + // Define the relationship to the User (Faculty) public function department() diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index dc94744..d780a5a 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -22,6 +22,7 @@ class DatabaseSeeder extends Seeder ActivitiesAttendedResponsesTableSeeder::class, ActivitiesOrganisedTableSeeder::class, IvOrganisedTableSeeder::class, + PublicationSeeder::class, ]); // User::factory()->create([ diff --git a/database/seeders/PublicationSeeder.php b/database/seeders/PublicationSeeder.php new file mode 100644 index 0000000..65435c4 --- /dev/null +++ b/database/seeders/PublicationSeeder.php @@ -0,0 +1,133 @@ +subDays(rand(30, 365))->addHours(rand(0, 23))->addMinutes(rand(0, 59)); + $endDate = (clone $startDate)->addDays(rand(1, 5))->addHours(rand(0, 23))->addMinutes(rand(0, 59)); + $numDays = $startDate->diffInDays($endDate) ?: 1; + + // Determine if the publication is indexed + $isPeer = $isPeerReviewed[array_rand($isPeerReviewed)]; + $scopusLink = $isPeer === 'yes' && rand(0, 1) ? 'https://www.scopus.com/record/display.uri?eid=2-s2.0-' . rand(10000000000, 99999999999) : null; + $sciLink = $isPeer === 'yes' && rand(0, 1) ? 'https://www.webofscience.com/wos/woscc/full-record/' . rand(100000, 999999) : null; + + // Create the publication record + Publication::create([ + 'department_id' => rand(1, 5), + 'first_author_name' => $firstAuthorNames[array_rand($firstAuthorNames)], + 'co_authors' => $coAuthors[array_rand($coAuthors)], + 'start_date' => $startDate->format('Y-m-d H:i:s'), + 'end_date' => $endDate->format('Y-m-d H:i:s'), + 'num_days' => $numDays, + 'activity_type' => $activityTypes[array_rand($activityTypes)], + 'title' => $titles[array_rand($titles)], + 'affiliation' => $affiliations[array_rand($affiliations)], + 'organizing_institute' => $organizingInstitutes[array_rand($organizingInstitutes)], + 'venue_address' => $venueAddresses[array_rand($venueAddresses)], + 'is_peer_reviewed' => $isPeer, + 'scopus_link' => $scopusLink, + 'sci_link' => $sciLink, + 'paper_file' => null, // Null for paper file + 'faculty_id' => rand(1, 5), + ]); + } + } +} \ No newline at end of file diff --git a/resources/views/emails/missing-proofs.blade.php b/resources/views/emails/missing-proofs.blade.php new file mode 100644 index 0000000..4cbb5c6 --- /dev/null +++ b/resources/views/emails/missing-proofs.blade.php @@ -0,0 +1,85 @@ + + + + Missing Proofs Notification + + + +
+

Missing Proofs Notification

+ +

Dear {{ $faculty->name }},

+ +

Our records indicate that you have missing proofs for the following entries. Please submit the required proofs at your earliest convenience:

+ + + + + + + + + + + @foreach ($items as $item) + + + + + + @endforeach + +
TypeName/TitleDetails
{{ $item['type'] }}{{ $item['primary_name'] }} +
    + @foreach ($item['details'] as $key => $value) +
  • {{ $key }}: {{ $value }}
  • + @endforeach +
+
+ +

Please log in to the faculty portal to upload the missing proofs. If you have any questions or need assistance, please contact the administrative office.

+ +

Thank you for your prompt attention to this matter.

+ + +
+ + \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index b2b1d7e..5f02569 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,7 @@ use App\Http\Controllers\CoordinatorController; use App\Http\Controllers\ExternalEngagementController; use App\Http\Controllers\FacultyController; use App\Http\Controllers\IvOrganisedController; +use App\Http\Controllers\MissingProofsController; use App\Http\Controllers\OnlineCoursesController; use App\Http\Controllers\PatentsController; use App\Http\Controllers\PublicationsController; @@ -259,6 +260,8 @@ Route::middleware(['auth', CheckRole::class . ':Faculty'])->group(function () { Route::put('/faculty/Patents/{id}', [PatentsController::class, 'update'])->name('faculty.Patents.update'); }); +Route::post('/missing-proofs/check', [MissingProofsController::class, 'checkAndSendEmails'])->name('missing-proofs.check'); + // API Resources Route::apiResources([ 'roles' => RoleController::class,