Skip to content

Commit

Permalink
Merge pull request #18 from seiyanz16/main
Browse files Browse the repository at this point in the history
Enhance Internship Management with Role-based Company Filtering, PDF Export, and Date Validation
  • Loading branch information
akechi17 authored Feb 3, 2025
2 parents 0e46ead + 14d25c2 commit ca14a8b
Show file tree
Hide file tree
Showing 16 changed files with 555 additions and 209 deletions.
21 changes: 21 additions & 0 deletions app/Http/Controllers/Api/ApplianceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
105 changes: 105 additions & 0 deletions app/Http/Controllers/Api/ExportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace App\Http\Controllers\Api;

// use ZipArchive;
use mikehaertl\pdftk\Pdf;
use Carbon\Carbon;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class ExportController extends Controller
{
public function exportJournal(Request $request, $id)
{
$user = auth()->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 = $id;
$company = $user->companies()->find($companyId);
if (!$company) {
return response()->json(['error' => 'Company not found!'], 404);
}
$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();

if ($presences->isEmpty()) {
return response()->json(['error' => 'No presences found!'], 404);
}

$journals = $user->journals()
->where('company_id', $companyId)
->whereDate('date', '<=', Carbon::now())
->orderBy('date', 'asc')
->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,
'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);
}
}
2 changes: 2 additions & 0 deletions app/Http/Controllers/JournalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions app/Http/Controllers/ScoreController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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)]);
Expand Down
144 changes: 90 additions & 54 deletions app/Http/Controllers/StudentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -18,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 . '%');
Expand Down Expand Up @@ -121,24 +123,41 @@ 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')
->where('id', $id)
->first();
}

$company = $company ? $user->companies()->first() : null;
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');
Expand All @@ -147,32 +166,36 @@ public function edit(Request $request, $id)
'status' => true,
'message' => 'Data siswa ditemukan',
'student' => $user,
'company' => $company,
'companiesData' => $companiesData,
'courses' => $courses,
];
} else {
$context = [
'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')
Expand All @@ -186,46 +209,59 @@ 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) {
$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],
[
'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;

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');
Expand Down
1 change: 1 addition & 0 deletions app/Models/Score.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Score extends Model
'company_id',
'name',
'score',
'type',
];

protected $appends = [
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
Loading

0 comments on commit ca14a8b

Please sign in to comment.