From 0ad3a0c0ba4579b83fa01cf995159338009d17f0 Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Thu, 16 Jan 2025 14:39:32 +0700 Subject: [PATCH 1/7] feat: multiple company --- app/Http/Controllers/JournalController.php | 2 + app/Http/Controllers/StudentController.php | 109 +++++++++++---------- database/seeders/MenuSeeder.php | 4 +- resources/views/students/edit.blade.php | 48 ++++----- 4 files changed, 81 insertions(+), 82 deletions(-) diff --git a/app/Http/Controllers/JournalController.php b/app/Http/Controllers/JournalController.php index 9fc8cf3..7599e06 100644 --- a/app/Http/Controllers/JournalController.php +++ b/app/Http/Controllers/JournalController.php @@ -27,6 +27,8 @@ public function getData($userId, $companyId, $search = null, $status = null, $so $sortType = 'asc'; } $journals = $journals->orderBy($sort, $sortType); + } else { + $journals = $journals->orderBy('date', 'desc'); } if ($paginate) { $journals = $journals->paginate(10); diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/StudentController.php index 8acbd00..16e603d 100644 --- a/app/Http/Controllers/StudentController.php +++ b/app/Http/Controllers/StudentController.php @@ -5,6 +5,7 @@ use Carbon\Carbon; use App\Models\User; use App\Models\Course; +use App\Models\Company; use Illuminate\Http\Request; use App\Models\PresenceStatus; @@ -121,16 +122,7 @@ public function edit(Request $request, $id) if ($company) { $user = User::whereRelation('roles', 'name', 'student') ->where('id', $id) - ->whereHas('companies', function($query) use ($company) { - $query->where('company_id', $company); - }) - ->with(['companies' => function($query) use ($company) { - $query->where('company_id', $company); - }, 'courses' => function($query) use ($company) { - $query->first(); - },'internDates' => function($query) use ($company) { - $query->where('company_id', $company); - }]) + ->with(['companies', 'internDates']) ->first(); } else { $user = User::whereRelation('roles', 'name', 'student') @@ -138,7 +130,17 @@ public function edit(Request $request, $id) ->first(); } - $company = $company ? $user->companies()->first() : null; + $companiesData = $user->companies->map(function ($company) use ($user) { + $internDate = $user->internDates->where('company_id', $company->id)->first(); + return [ + 'id' => $company->id, + 'name' => $company->name, + 'start_date' => $internDate?->start_date, + 'end_date' => $internDate?->end_date, + 'extend' => $internDate?->extend, + 'finished' => $internDate?->finished, + ]; + }); if ($user) { $courses = Course::where('department_id', $user->departments()->first()->id)->pluck('name', 'id'); @@ -147,7 +149,7 @@ public function edit(Request $request, $id) 'status' => true, 'message' => 'Data siswa ditemukan', 'student' => $user, - 'company' => $company, + 'companiesData' => $companiesData, 'courses' => $courses, ]; } else { @@ -155,24 +157,28 @@ public function edit(Request $request, $id) 'status' => false, 'message' => 'Data siswa tidak ditemukan', 'student' => null, - 'company' => $company, + 'companiesData' => $companiesData, 'courses' => null ]; } + // dd($context); + return view('students.edit', $context); } public function update(Request $request, $id) { - $company = $request->query('company'); - $company = $company ? decrypt($company) : null; $id = decrypt($id); $request->validate([ 'name' => 'required|string|max:255', 'skills' => 'nullable|string', 'course_id' => 'required|exists:courses,id', + 'companies.*.start_date' => 'nullable|date', + 'companies.*.end_date' => 'nullable|date', + 'companies.*.extend' => 'nullable|integer', + 'companies.*.finished' => 'nullable|boolean', ]); $user = User::whereRelation('roles', 'name', 'student') @@ -186,46 +192,45 @@ public function update(Request $request, $id) ]); $user->courses()->sync($request->course_id); - if ($company) { - - $request->validate([ - 'start_date' => 'required|date', - 'end_date' => 'required|date', - 'extend' => 'nullable|integer', - 'finished' => 'required|boolean', - ]); - - $user->internDates()->where('company_id', $company)->update([ - 'start_date' => $request->start_date, - 'end_date' => $request->end_date, - 'extend' => $request->extend, - 'finished' => $request->finished, - ]); - - $presencePending = PresenceStatus::where('name', 'Pending')->first('id')->id; - $startDate = Carbon::parse($request->start_date); - $endDate = Carbon::parse($request->end_date); - - for ($i = $startDate; $i <= $endDate; $i->addDay()) { - $presence = $user->presences()->where('company_id', $company)->where('date', $i)->first(); - $journal = $user->journals()->where('company_id', $company)->where('date', $i)->first(); - - if (! $presence) { - $user->presences()->create([ - 'company_id' => $company, - 'date' => $i, - 'presence_status_id' => $presencePending, - ]); - } - if (! $journal) { - $user->journals()->create([ - 'company_id' => $company, - 'date' => $i, - ]); + if ($request->has('companies')) { + foreach ($request->companies as $companyId => $data) { + $company = Company::find($companyId); + if ($company) { + $user->internDates()->updateOrCreate( + ['company_id' => $companyId], + [ + 'start_date' => $data['start_date'] ?? null, + 'end_date' => $data['end_date'] ?? null, + 'extend' => $data['extend'] ?? 0, + 'finished' => $data['finished'] ?? 0, + ] + ); + + $presencePending = PresenceStatus::where('name', 'Pending')->first('id')->id; + $startDate = Carbon::parse($data['start_date']); + $endDate = Carbon::parse($data['end_date']); + + for ($i = $startDate; $i <= $endDate; $i->addDay()) { + $presence = $user->presences()->where('company_id', $companyId)->where('date', $i)->first(); + if (!$presence) { + $user->presences()->create([ + 'company_id' => $companyId, + 'date' => $i, + 'presence_status_id' => $presencePending, + ]); + } + + $journal = $user->journals()->where('company_id', $companyId)->where('date', $i)->first(); + if (!$journal) { + $user->journals()->create([ + 'company_id' => $companyId, + 'date' => $i, + ]); + } + } } } } - return redirect()->route('students.index')->with('success', 'Data siswa berhasil diperbarui'); } else { return redirect()->route('students.index')->with('error', 'Data siswa tidak ditemukan'); diff --git a/database/seeders/MenuSeeder.php b/database/seeders/MenuSeeder.php index 4e2b4e5..68f74f6 100644 --- a/database/seeders/MenuSeeder.php +++ b/database/seeders/MenuSeeder.php @@ -69,7 +69,7 @@ public function run() 'url' => 'news?category=school&school=' . encrypt($school->id), 'status' => 1, 'order' => 31, - 'parent_id' => 4, + 'parent_id' => 5, 'permission_id' => Permission::where('name', 'news-list')->first()->id, ], [ @@ -78,7 +78,7 @@ public function run() 'url' => 'news?category=department&school=' . encrypt($school->id), 'status' => 1, 'order' => 32, - 'parent_id' => 4, + 'parent_id' => 5, 'permission_id' => Permission::where('name', 'news-list')->first()->id, ], [ diff --git a/resources/views/students/edit.blade.php b/resources/views/students/edit.blade.php index b4bc6bb..cb948c8 100644 --- a/resources/views/students/edit.blade.php +++ b/resources/views/students/edit.blade.php @@ -1,8 +1,7 @@ @extends('layouts.dashboard') @section('dashboard-content') - + @error(['name', 'course_id', 'skills', 'company', 'start_date', 'end_date', 'extend'])
{{ $message }}
@enderror @@ -41,39 +40,32 @@ name="skills" value="{{ $student->skills }}" placeholder="HTML, CSS, JavaScript, PHP, Laravel, MySQL, Bootstrap" /> @endif - - @if ($company) - - - - +
+ @foreach ($companiesData as $company) +
+ + + + + + + + +
- internDates()->where('company_id', $company->id)->first()?->finished == 0? 'checked': '' }}> - + +
- internDates()->where('company_id', $company->id)->first()?->finished == 1? 'checked': '' }}> - + +
- @else - - - - @endif +
+ @endforeach +
@endsection From 53cb27af38103f748ce287c83dadd49d33c75e07 Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Sun, 19 Jan 2025 08:07:18 +0700 Subject: [PATCH 2/7] fix: implement role-based company filtering --- app/Http/Controllers/StudentController.php | 43 +++++++++++++++------- resources/views/students/index.blade.php | 28 +++++++++----- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/StudentController.php index 16e603d..d98505d 100644 --- a/app/Http/Controllers/StudentController.php +++ b/app/Http/Controllers/StudentController.php @@ -19,7 +19,8 @@ public function getData($search=null, $status=null, $school=null, $department=nu $isTeacher = auth()->user()->hasRole('teacher'); $isMentor = auth()->user()->hasRole('mentor'); - $users = User::whereRelation('roles', 'name', 'student'); + $users = User::whereRelation('roles', 'name', 'student') + ->with(['companies', 'internDates', 'schools', 'departments']); if ($search) { $users = $users->where('name', 'like', '%' . $search . '%') ->orWhere('email', 'like', '%' . $search . '%'); @@ -129,18 +130,34 @@ public function edit(Request $request, $id) ->where('id', $id) ->first(); } - - $companiesData = $user->companies->map(function ($company) use ($user) { - $internDate = $user->internDates->where('company_id', $company->id)->first(); - return [ - 'id' => $company->id, - 'name' => $company->name, - 'start_date' => $internDate?->start_date, - 'end_date' => $internDate?->end_date, - 'extend' => $internDate?->extend, - 'finished' => $internDate?->finished, - ]; - }); + if (auth()->user()->hasRole('mentor')) { + $mentorCompanyIds = auth()->user()->companies->pluck('id')->toArray(); + $companiesData = $user->companies->filter(function ($company) use ($mentorCompanyIds) { + return in_array($company->id, $mentorCompanyIds); + })->map(function ($company) use ($user) { + $internDate = $user->internDates->where('company_id', $company->id)->first(); + return [ + 'id' => $company->id, + 'name' => $company->name, + 'start_date' => $internDate?->start_date, + 'end_date' => $internDate?->end_date, + 'extend' => $internDate?->extend, + 'finished' => $internDate?->finished, + ]; + }); + } else { + $companiesData = $user->companies->map(function ($company) use ($user) { + $internDate = $user->internDates->where('company_id', $company->id)->first(); + return [ + 'id' => $company->id, + 'name' => $company->name, + 'start_date' => $internDate?->start_date, + 'end_date' => $internDate?->end_date, + 'extend' => $internDate?->extend, + 'finished' => $internDate?->finished, + ]; + }); + } if ($user) { $courses = Course::where('department_id', $user->departments()->first()->id)->pluck('name', 'id'); diff --git a/resources/views/students/index.blade.php b/resources/views/students/index.blade.php index c2cbeda..73bf3ef 100644 --- a/resources/views/students/index.blade.php +++ b/resources/views/students/index.blade.php @@ -40,9 +40,15 @@ @foreach ($students as $student) @php - $company = $student->companies()->first(); + $companies = $student->companies->filter(function($company) { + if (auth()->user()->hasRole('mentor')) { + return auth()->user()->companies->pluck('id')->contains($company->id); + } + + return true; + }); @endphp - @if (!$company) + @if ($companies->isEmpty()) {{ $student->internDates()->first()?->extend }} @else + @foreach ($companies as $company) @php - $startDate = $student - ->internDates() - ->where('company_id', $company->id) - ->first()?->start_date; - $endDate = $student - ->internDates() - ->where('company_id', $company->id) - ->first()?->end_date; + $internDate = $student->internDates()->where('company_id', $company->id)->first(); + $startDate = $internDate?->start_date; + $endDate = $internDate?->end_date; + $extend = $internDate?->extend; + $finished = $internDate?->finished; @endphp @@ -163,6 +167,10 @@ class="badge badge-sm bg-gradient-{{ $student->internDates()->where('company_id' + @if (auth()->user()->hasRole('mentor')) + @break + @endif + @endforeach @endif @endforeach From 4dac6c189d9ea4d6d74401e9a1c898b839357a15 Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Sun, 19 Jan 2025 12:16:17 +0700 Subject: [PATCH 3/7] feat: pdf export api export pdf with pdftk --- app/Http/Controllers/Api/ExportController.php | 95 ++++++++++++ composer.json | 1 + composer.lock | 141 +++++++++++++++++- routes/api.php | 3 + 4 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Api/ExportController.php diff --git a/app/Http/Controllers/Api/ExportController.php b/app/Http/Controllers/Api/ExportController.php new file mode 100644 index 0000000..9886c4e --- /dev/null +++ b/app/Http/Controllers/Api/ExportController.php @@ -0,0 +1,95 @@ +user(); + $courseName = $user->courses->first()?->name; + $courseLevel = $courseName ? explode(' ', $courseName)[0] : 'N/A'; + + $formattedDateOfBirth = $user->date_of_birth + ? Carbon::parse($user->date_of_birth)->translatedFormat('j F Y') + : 'N/A'; + + $gender = match ($user->gender) { + 'male' => 'Laki-Laki', + 'female' => 'Perempuan' + }; + + $companyId = $request->query('company', $user->companies->first()->id); + + $company = $user->companies()->find($companyId); + $companyName = $company?->name ?? 'N/A'; + + $presences = $user->presences() + ->where('company_id', $companyId) + ->whereDate('date', '<=', Carbon::now()) + ->orderBy('date', 'asc') + ->get() + ->filter(fn($presence) => !is_null($presence->check_in)) + ->values(); + + $journals = $user->journals() + ->where('company_id', $companyId) + ->whereDate('date', '<=', Carbon::now()) + ->orderBy('date', 'asc') + ->get() + ->filter(fn($journal) => !is_null($journal->work_type)) + ->values(); + + $formFields = [ + 'namasiswa' => $user->name, + 'kelas' => $courseLevel, + 'alamat_siswa' => $user->address, + 'jurusan' => $user->departments->first()?->description, + 'instansi_nama' => $companyName, + 'kelasjurusan' => $courseName, + 'ttl' => $formattedDateOfBirth, + 'gender' => $gender, + ]; + + foreach ($presences as $index => $presence) { + $i = $index + 1; + $formFields["tanggal$i"] = Carbon::parse($presence->date)->translatedFormat('l, j F Y'); + $formFields["checkin$i"] = $presence->check_in; + $formFields["checkout$i"] = $presence->check_out ?? 'N/A'; + } + + foreach ($journals as $index => $journal) { + $i = $index + 1; + $formFields["no$i"] = $i; + $formFields["bidang$i"] = $journal->work_type; + $formFields["uraian$i"] = $journal->description; + $formFields["tgl_jurnal$i"] = Carbon::parse($journal->date)->translatedFormat('l, j F Y'); + } + + $templatePath = ''; + if (count($presences) <= 93 || count($journals) <= 93) { + $templatePath = public_path('template-pdf/template_3_month.pdf'); + } else { + $templatePath = public_path('template-pdf/template_6_month.pdf'); + } + + if (!file_exists($templatePath)) { + return response()->json(['error' => 'PDF template not found!'], 404); + } + + $fileName = $user->id . time() . '.pdf'; + $tempPath = storage_path('storage/journals/' . $fileName); + $outputPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $fileName; + $pdf = new Pdf($templatePath); + $pdf->fillForm($formFields)->flatten()->saveAs($outputPath); + + return response()->download($outputPath, $fileName)->deleteFileAfterSend(true); + } +} diff --git a/composer.json b/composer.json index d35f0cd..d20322f 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "laravel/tinker": "^2.7", "maatwebsite/excel": "^3.1", "meilisearch/meilisearch-php": "^1.0", + "mikehaertl/php-pdftk": "^0.13.1", "owen-it/laravel-auditing": "^13.0", "spatie/laravel-permission": "^5.7" }, diff --git a/composer.lock b/composer.lock index 53c3141..9d04daa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "24e4eb0d49ea1511e0ad0067e3d9788a", + "content-hash": "20003ba38720bb0f0b87ef46cf44787c", "packages": [ { "name": "bacon/bacon-qr-code", @@ -2750,6 +2750,145 @@ }, "time": "2024-08-26T23:09:54+00:00" }, + { + "name": "mikehaertl/php-pdftk", + "version": "0.13.1", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-pdftk.git", + "reference": "3851b08c1027489e48387d7c14c27bc295d98239" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-pdftk/zipball/3851b08c1027489e48387d7c14c27bc295d98239", + "reference": "3851b08c1027489e48387d7c14c27bc295d98239", + "shasum": "" + }, + "require": { + "mikehaertl/php-shellcommand": "^1.6.3", + "mikehaertl/php-tmpfile": "^1.1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\pdftk\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Haertl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A PDF conversion and form utility based on pdftk.", + "keywords": [ + "pdf", + "pdftk" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-pdftk/issues", + "source": "https://github.com/mikehaertl/php-pdftk/tree/0.13.1" + }, + "time": "2023-11-03T16:06:08+00:00" + }, + { + "name": "mikehaertl/php-shellcommand", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-shellcommand.git", + "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-shellcommand/zipball/e79ea528be155ffdec6f3bf1a4a46307bb49e545", + "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <=9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\shellcommand\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "An object oriented interface to shell commands", + "keywords": [ + "shell" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-shellcommand/issues", + "source": "https://github.com/mikehaertl/php-shellcommand/tree/1.7.0" + }, + "time": "2023-04-19T08:25:22+00:00" + }, + { + "name": "mikehaertl/php-tmpfile", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-tmpfile.git", + "reference": "a5392bed91f67e2849a7cb24075d346468e1b1a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-tmpfile/zipball/a5392bed91f67e2849a7cb24075d346468e1b1a8", + "reference": "a5392bed91f67e2849a7cb24075d346468e1b1a8", + "shasum": "" + }, + "require-dev": { + "php": ">=5.3.0", + "phpunit/phpunit": ">4.0 <=9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\tmp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A convenience class for temporary files", + "keywords": [ + "files" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-tmpfile/issues", + "source": "https://github.com/mikehaertl/php-tmpfile/tree/1.3.0" + }, + "time": "2024-10-14T16:12:48+00:00" + }, { "name": "monolog/monolog", "version": "3.7.0", diff --git a/routes/api.php b/routes/api.php index 0346c57..0c0e7ea 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,6 +3,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\Api\AuthController; +use App\Http\Controllers\Api\ExportController; use App\Http\Controllers\Api\NewsController; use App\Http\Controllers\Api\UserController; use App\Http\Controllers\Api\JournalController; @@ -61,6 +62,8 @@ Route::resource('journals', JournalController::class)->except(['create', 'edit']); + Route::post('export-journal', [ExportController::class, 'exportJournal']); + Route::get('/today-activities', [PresenceController::class, 'todayActivity']); Route::resource('presences', PresenceController::class)->except(['create', 'edit']); From 48857f6696494104b20167dbad69ac8d58ac8da1 Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Sun, 19 Jan 2025 15:31:23 +0700 Subject: [PATCH 4/7] feat: add validation to prevent date overlap with other internships --- .../Controllers/Api/ApplianceController.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/Http/Controllers/Api/ApplianceController.php b/app/Http/Controllers/Api/ApplianceController.php index 1af6366..0993744 100644 --- a/app/Http/Controllers/Api/ApplianceController.php +++ b/app/Http/Controllers/Api/ApplianceController.php @@ -73,6 +73,27 @@ public function editDate(Request $request, $id) $user = auth()->user(); + // Parse the start and end date + $startDate = Carbon::parse($request->start_date); + $endDate = Carbon::parse($request->end_date); + + // Check if the start and end dates overlap with any other company's internship dates + $overlapCheck = $user->internDates()->where('company_id', '!=', $id) + ->where(function ($query) use ($startDate, $endDate) { + $query->whereBetween('start_date', [$startDate, $endDate]) + ->orWhereBetween('end_date', [$startDate, $endDate]) + ->orWhere(function ($query) use ($startDate, $endDate) { + $query->where('start_date', '<=', $startDate) + ->where('end_date', '>=', $endDate); + }); + })->exists(); + + if ($overlapCheck) { + return response()->json([ + 'message' => 'The selected dates overlap with another company\'s internship dates.', + ], 400); + } + try { $user->internDates()->where('company_id', $id)->update($request->all()); From 6c167bd051b7c487cb845d59a074bf83e78fe0ca Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Mon, 20 Jan 2025 10:50:46 +0700 Subject: [PATCH 5/7] fix: enhance student view with dropdown action added dropdown menu for students with multiple companies, providing separate actions for each company --- app/Http/Controllers/StudentController.php | 18 +- resources/views/students/index.blade.php | 253 ++++++++++----------- 2 files changed, 137 insertions(+), 134 deletions(-) diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/StudentController.php index d98505d..7fb127e 100644 --- a/app/Http/Controllers/StudentController.php +++ b/app/Http/Controllers/StudentController.php @@ -213,6 +213,22 @@ public function update(Request $request, $id) foreach ($request->companies as $companyId => $data) { $company = Company::find($companyId); if ($company) { + $startDate = Carbon::parse($data['start_date']); + $endDate = Carbon::parse($data['end_date']); + + $overlapCheck = $user->internDates()->where('company_id', '!=', $companyId) + ->where(function ($query) use ($startDate, $endDate) { + $query->whereBetween('start_date', [$startDate, $endDate]) + ->orWhereBetween('end_date', [$startDate, $endDate]) + ->orWhere(function ($query) use ($startDate, $endDate) { + $query->where('start_date', '<=', $startDate) + ->where('end_date', '>=', $endDate); + }); + })->exists(); + + if ($overlapCheck) { + return back()->with('error', 'Tanggal yang dipilih tidak sesuai.'); + } $user->internDates()->updateOrCreate( ['company_id' => $companyId], [ @@ -224,8 +240,6 @@ public function update(Request $request, $id) ); $presencePending = PresenceStatus::where('name', 'Pending')->first('id')->id; - $startDate = Carbon::parse($data['start_date']); - $endDate = Carbon::parse($data['end_date']); for ($i = $startDate; $i <= $endDate; $i->addDay()) { $presence = $user->presences()->where('company_id', $companyId)->where('date', $i)->first(); diff --git a/resources/views/students/index.blade.php b/resources/views/students/index.blade.php index 73bf3ef..816cf95 100644 --- a/resources/views/students/index.blade.php +++ b/resources/views/students/index.blade.php @@ -39,139 +39,128 @@ @foreach ($students as $student) - @php - $companies = $student->companies->filter(function($company) { - if (auth()->user()->hasRole('mentor')) { - return auth()->user()->companies->pluck('id')->contains($company->id); - } - - return true; - }); - @endphp - @if ($companies->isEmpty()) - - - - - - - @can('monitor-list') - - - @endcan - - - - - - - - {{ $student->name }} - {{ $student->courses()->first()?->name }} - -
    - @if ($student->skills) - @foreach (explode(',', $student->skills) as $skill) -
  • {{ $skill }}
  • - @endforeach - @endif -
- - {{ $student->companies()->first()?->name }} - {{ $student->internDates()->first()?->start_date }} - {{ $student->internDates()->first()?->end_date }} - {{ $student->internDates()->first()?->extend }} - - @else - @foreach ($companies as $company) - @php - $internDate = $student->internDates()->where('company_id', $company->id)->first(); - $startDate = $internDate?->start_date; - $endDate = $internDate?->end_date; - $extend = $internDate?->extend; - $finished = $internDate?->finished; - @endphp - - - - - - - @can('monitor-list') - - - @endcan - - - - - - - - - {{ $student->name }} - {{ $student->courses->first()?->name }} - -
    - @if ($student->skills) - @foreach (explode(',', $student->skills) as $skill) -
  • {{ $skill }}
  • + @php + $companies = $student->companies->filter(function($company) { + if (auth()->user()->hasRole('mentor')) { + return auth()->user()->companies->pluck('id')->contains($company->id); + } + return true; + }); + @endphp + + + @if ($companies->count() > 1) +
+ + @else + @foreach ($companies as $company) + + + + + + + @can('monitor-list') + + + + @endcan + + + + + + + @endforeach + @endif + + + + + {{ $student->name }} + {{ $student->courses->first()?->name }} + +
    + @if ($student->skills) + @foreach (explode(',', $student->skills) as $skill) +
  • {{ $skill }}
  • + @endforeach + @endif +
+ + + @foreach ($companies as $company) + {{ $company->name }} + @endforeach + + + @foreach ($companies as $company) + @php + $internDate = $student->internDates()->where('company_id', $company->id)->first(); + $startDate = $internDate?->start_date; + @endphp + {{ $startDate ? \Carbon\Carbon::parse($startDate)->format('d-m-Y') : 'Belum Diisi' }} + @endforeach + + + @foreach ($companies as $company) + @php + $internDate = $student->internDates()->where('company_id', $company->id)->first(); + $endDate = $internDate?->end_date; + @endphp + {{ $endDate ? \Carbon\Carbon::parse($endDate)->format('d-m-Y') : 'Belum Diisi' }} + @endforeach + + + @foreach ($companies as $company) + @php + $internDate = $student->internDates()->where('company_id', $company->id)->first(); + @endphp + {{ $internDate?->extend }} bulan + @endforeach + + + @foreach ($companies as $company) + @php + $internDate = $student->internDates()->where('company_id', $company->id)->first(); + @endphp + + {{ $internDate?->finished ? 'Selesai' : 'PKL' }} + + @endforeach + + @endforeach From 9b5cb8e1f91a6e43a479a9693ea29b5849d8e125 Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Thu, 30 Jan 2025 08:29:13 +0700 Subject: [PATCH 6/7] fix: retrieve company id from url parameter --- app/Http/Controllers/Api/ExportController.php | 16 +++++++++++++--- routes/api.php | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/ExportController.php b/app/Http/Controllers/Api/ExportController.php index 9886c4e..c5a361e 100644 --- a/app/Http/Controllers/Api/ExportController.php +++ b/app/Http/Controllers/Api/ExportController.php @@ -11,7 +11,7 @@ class ExportController extends Controller { - public function exportJournal(Request $request) + public function exportJournal(Request $request, $id) { $user = auth()->user(); $courseName = $user->courses->first()?->name; @@ -26,9 +26,11 @@ public function exportJournal(Request $request) 'female' => 'Perempuan' }; - $companyId = $request->query('company', $user->companies->first()->id); - + $companyId = $id; $company = $user->companies()->find($companyId); + if (!$company) { + return response()->json(['error' => 'Company not found!'], 404); + } $companyName = $company?->name ?? 'N/A'; $presences = $user->presences() @@ -39,6 +41,10 @@ public function exportJournal(Request $request) ->filter(fn($presence) => !is_null($presence->check_in)) ->values(); + if ($presences->isEmpty()) { + return response()->json(['error' => 'No presences found!'], 404); + } + $journals = $user->journals() ->where('company_id', $companyId) ->whereDate('date', '<=', Carbon::now()) @@ -46,6 +52,10 @@ public function exportJournal(Request $request) ->get() ->filter(fn($journal) => !is_null($journal->work_type)) ->values(); + + if ($journals->isEmpty()) { + return response()->json(['error' => 'No journals found!'], 404); + } $formFields = [ 'namasiswa' => $user->name, diff --git a/routes/api.php b/routes/api.php index 0c0e7ea..969a4ec 100644 --- a/routes/api.php +++ b/routes/api.php @@ -62,7 +62,7 @@ Route::resource('journals', JournalController::class)->except(['create', 'edit']); - Route::post('export-journal', [ExportController::class, 'exportJournal']); + Route::post('export-journal/{id}', [ExportController::class, 'exportJournal']); Route::get('/today-activities', [PresenceController::class, 'todayActivity']); Route::resource('presences', PresenceController::class)->except(['create', 'edit']); From 14d25c2b6aae970e2fc947d4fdb5073907c5d61f Mon Sep 17 00:00:00 2001 From: seiyanz16 Date: Thu, 30 Jan 2025 16:57:22 +0700 Subject: [PATCH 7/7] feat: add type for scores --- app/Http/Controllers/ScoreController.php | 3 ++ app/Models/Score.php | 1 + ..._01_30_135142_add_type_to_scores_table.php | 28 +++++++++++++++++++ resources/views/scores/create.blade.php | 7 +++++ resources/views/scores/edit.blade.php | 7 +++++ resources/views/scores/index.blade.php | 4 +++ 6 files changed, 50 insertions(+) create mode 100644 database/migrations/2025_01_30_135142_add_type_to_scores_table.php diff --git a/app/Http/Controllers/ScoreController.php b/app/Http/Controllers/ScoreController.php index 9bd3ff2..85f0bad 100644 --- a/app/Http/Controllers/ScoreController.php +++ b/app/Http/Controllers/ScoreController.php @@ -89,6 +89,7 @@ public function store(Request $request) 'company_id' => 'required|exists:companies,id', 'name' => 'required', 'score' => 'required|integer', + 'type' => 'required|in:teknis,non-teknis' ]); Score::create($request->all()); @@ -165,12 +166,14 @@ public function update(Request $request, $id) $request->validate([ 'name' => 'required', 'score' => 'required|integer', + 'type' => 'required|in:teknis,non-teknis' ]); $score = Score::find($id); $score->update([ 'name' => $request->name, 'score' => $request->score, + 'type' => $request->type, ]); return redirect()->route('scores.index', ['user' => encrypt($score->user_id), 'company' => encrypt($score->company_id)]); diff --git a/app/Models/Score.php b/app/Models/Score.php index 084479c..182b007 100644 --- a/app/Models/Score.php +++ b/app/Models/Score.php @@ -14,6 +14,7 @@ class Score extends Model 'company_id', 'name', 'score', + 'type', ]; protected $appends = [ diff --git a/database/migrations/2025_01_30_135142_add_type_to_scores_table.php b/database/migrations/2025_01_30_135142_add_type_to_scores_table.php new file mode 100644 index 0000000..18da51d --- /dev/null +++ b/database/migrations/2025_01_30_135142_add_type_to_scores_table.php @@ -0,0 +1,28 @@ +enum('type', ['teknis', 'non-teknis'])->default('teknis'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('scores', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +}; diff --git a/resources/views/scores/create.blade.php b/resources/views/scores/create.blade.php index 9012045..7ae8803 100644 --- a/resources/views/scores/create.blade.php +++ b/resources/views/scores/create.blade.php @@ -5,6 +5,13 @@ +
+ + +
diff --git a/resources/views/scores/edit.blade.php b/resources/views/scores/edit.blade.php index 6ab770c..959255e 100644 --- a/resources/views/scores/edit.blade.php +++ b/resources/views/scores/edit.blade.php @@ -5,6 +5,13 @@ +
+ + +
@endsection diff --git a/resources/views/scores/index.blade.php b/resources/views/scores/index.blade.php index 8294315..70287fc 100644 --- a/resources/views/scores/index.blade.php +++ b/resources/views/scores/index.blade.php @@ -13,6 +13,9 @@ Subyek + + Tipe + Nilai @@ -41,6 +44,7 @@ class="bi bi-trash"> @endcan {{ $data->name }} + {{ $data->type === 'teknis' ? 'Teknis' : 'Non Teknis' }} {{ $data->score }}