MIF_E31210063/MaidMatching/app/Http/Controllers/api/JobController.php

576 lines
19 KiB
PHP

<?php
namespace App\Http\Controllers\api;
use App\Models\Job;
use App\Models\Profile;
use App\Models\JobSkill;
use App\Models\Applicant;
use App\Models\UserSkill;
use Illuminate\Support\Str;
use App\Models\JobParameter;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use App\Http\Resources\JobResource;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
class JobController extends Controller
{
public function index(Request $request)
{
$jobs = Job::select("*")->whereRaw('recruit_id IS NULL');
$search = isset($request->search) ? $request->search : '';
if (!empty($search)) {
$jobs->where(function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
}
// $length = intval(isset($request->length) ? $request->length : 10);
// $start = intval(isset($request->start) ? $request->start : 0);
// $jobs = $jobs->skip($start)->take($length)->get();
$jobs = $jobs->get();
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => JobResource::collection($jobs->loadMissing(['skills', 'parameters', 'applicants']))
], 200);
}
public function index2(Request $request)
{
$jobs = Job::select("*");
$search = isset($request->search['value']) ? $request->search['value'] : '';
if (!empty($search)) {
$jobs->where(function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
}
$total_data = $jobs->count();
$length = intval(isset($request->length) ? $request->length : 0);
$start = intval(isset($request->start) ? $request->start : 0);
if (!isset($request->length) || !isset($request->start)) {
$jobs = $jobs->get();
} else {
$jobs = $jobs->skip($start)->take($length)->get();
}
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => JobResource::collection($jobs->loadMissing(['skills', 'parameters', 'applicants'])),
'draw' => $request->draw,
'recordsTotal' => $total_data,
'recordsFiltered' => $total_data,
], 200);
}
public function show_applied_job(Request $request, $user_id)
{
$jobs = Job::select(["*","jobs.id", "jobs.user_id"])->join('applicants', 'applicants.job_id', 'jobs.id')
->where('applicants.user_id', $user_id);
$search = isset($request->search) ? $request->search : '';
if (!empty($search)) {
$jobs->where(function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
}
// $length = intval(isset($request->length) ? $request->length : 10);
// $start = intval(isset($request->start) ? $request->start : 0);
// $jobs = $jobs->skip($start)->take($length)->get();
$jobs = $jobs->get();
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => JobResource::collection($jobs->loadMissing(['skills', 'parameters', 'applicants']))
], 200);
}
public function owner_jobs(Request $request, $user_id)
{
$jobs = Job::where('user_id', $user_id);
$search = isset($request->search) ? $request->search : '';
if (!empty($search)) {
$jobs->where(function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
}
// $length = intval(isset($request->length) ? $request->length : 10);
// $start = intval(isset($request->start) ? $request->start : 0);
// $jobs = $jobs->skip($start)->take($length)->get();
$jobs = $jobs->get();
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => JobResource::collection($jobs->loadMissing(['skills', 'parameters']))
], 200);
}
public function show($id)
{
$job = Job::where('id', $id)->get();
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => JobResource::collection($job->loadMissing(['skills', 'parameters']))
], 200);
}
public function store(Request $request)
{
ini_set('max_execution_time', 600);
$validator = Validator::make($request->all(), [
'user_id' => 'required',
'name' => 'required',
'description' => 'required',
'accommodation' => 'required',
'working_days' => 'required',
'working_hours' => 'required',
'image' => 'required|file|mimes:jpg,png,jpeg|max:5048',
'salary' => 'required',
'address' => 'required',
'location' => 'required',
'recomended_age' => 'required',
], [
'required' => ':attribute harus diisi.',
'file' => ':attribute harus berupa file.',
'mimes' => 'File :attribute harus berformat jpg, jpeg, atau png.',
'max' => 'File :attribute tidak boleh lebih dari :max KB.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
// Upload File
$namaimage = $this->generateRandomString(33).time();
$ekstensiimage = $request->image->extension();
$pathimage = '/assets/storage/document/job/image/' . $namaimage . "." . $ekstensiimage;
$request->image->move(public_path('assets/storage/document/job/image'), $pathimage);
// End Upload File
$job = Job::create([
'user_id' => $request->input('user_id'),
'name' => $request->input('name'),
'description' => $request->input('description'),
'accommodation' => $request->input('accommodation'),
'working_days' => $request->input('working_days'),
'working_hours' => $request->input('working_hours'),
'image' => $pathimage,
'salary' => $request->input('salary'),
'address' => $request->input('address'),
'location' => $request->input('location'),
'recomended_age' => $request->input('recomended_age'),
]);
return response()->json([
'error' => false,
'message' => 'Job berhasil ditambahkan.',
'id' => $job->id,
'data' => null
]);
}
public function update(Request $request, $id)
{
ini_set('max_execution_time', 300);
$validator = Validator::make($request->all(), [
'name' => 'required',
'description' => 'required',
'accommodation' => 'required',
'working_days' => 'required',
'working_hours' => 'required',
'image' => 'required',
'salary' => 'required',
'address' => 'required',
'location' => 'required',
'recomended_age' => 'required',
], [
'required' => ':attribute harus diisi.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
$update = [
'name' => $request->input('name'),
'description' => $request->input('description'),
'image' => $request->input('image'),
'salary' => $request->input('salary'),
'address' => $request->input('address'),
'location' => $request->input('location'),
'recomended_age' => $request->input('recomended_age'),
];
$job = Job::findOrFail($id);
$job->update($update);
return response()->json([
'error' => false,
'message' => 'Job berhasil diubah.',
'data' => null
]);
}
public function destroy($id)
{
$job = Job::findOrFail($id);
$name = $job->name;
$job->delete();
return response()->json([
'error' => false,
'message' => 'Job '.$name.' berhasil dihapus.',
'data' => null
]);
}
public function add_skills(Request $request, $id) {
$validator = Validator::make($request->all(), [
'skills' => 'required|array',
], [
'required' => ':attribute harus diisi.',
'array' => ':attribute harus berupa array.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
$job = Job::find($id);
$skills = $request->input('skills');
foreach ($skills as $skill) {
if (!empty($skill)) {
JobSkill::create(['skill_id' => $skill, 'job_id' => $id]);
}
}
return response()->json([
'error' => false,
'message' => 'Berhasil menambahkan skill.',
'data' => null
]);
}
public function add_parameter(Request $request, $id) {
$validator = Validator::make($request->all(), [
'parameters' => 'required|array',
], [
'required' => ':attribute harus diisi.',
'array' => ':attribute harus berupa array.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
$job = Job::find($id);
$parameters = $request->input('parameters');
$jobParameters = [];
foreach ($parameters as $parameter) {
JobParameter::create(['job_id' => $id, 'parameter_id' => $parameter['parameter_id'], 'weight' => $parameter['weight']]);
}
return response()->json([
'error' => false,
'message' => 'Berhasil menambahkan parameter.',
'data' => null
]);
}
public function add_applicant(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'user_id' => 'required',
// 'param_distance' => 'required',
], [
'required' => ':attribute harus diisi.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
$job = Job::find($id);
$user_id = $request->input('user_id');
$profile = Profile::where('user_id', $user_id)->first();
$userSkills = UserSkill::where('user_id', $user_id)->pluck('skill_id');
$jobSkills = JobSkill::where('job_id', $id)->pluck('skill_id');
$now = Carbon::now();
$user_age = $now->diffInYears($profile->birthdate);
$param_age = abs($user_age - $job->recomended_age);
$param_salary = number_format($profile->desired_salary / $job->salary, 5, '.', '');
$param_skill = $userSkills->intersect($jobSkills)->count();
$userLocation = json_decode($profile->location, true);
$jobLocation = json_decode($job->location, true);
// Menghitung Garis Lurus
$param_distance = $this->haversine($userLocation, $jobLocation);
$formattedDistance = number_format($param_distance, 2);
$applicant = Applicant::create([
'user_id' => $user_id,
'job_id' => $id,
'param_age' => $param_age+1,
'param_salary' => $param_salary,
'param_skill' => $param_skill+1,
'param_distance' => $formattedDistance+1,
]);
return response()->json([
'error' => false,
'message' => 'Berhasil mendaftar di job ini.',
'data' => $applicant
]);
}
public function recruit_applicant(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'recruit_id' => 'required',
], [
'required' => ':attribute harus diisi.',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => Str::ucfirst($validator->errors()->first()),
'data' => null
]);
}
$update = [
'recruit_id' => $request->input('recruit_id'),
];
$job = Job::findOrFail($id);
$job->update($update);
return response()->json([
'error' => false,
'message' => 'Calon maid berhasil direkrut.',
'data' => null
]);
}
public function show_applicant(Request $request, $id)
{
$job = Job::findOrFail($id);
$applicants = Applicant::where('job_id', $id);
$order_by = $request->query('order_by', 'id');
$order_dir = $request->query('order_dir', 'asc');
if ($order_by === 'param_distance') {
$applicants = $applicants->orderBy('param_distance', $order_dir);
} elseif ($order_by === 'param_skill') {
$applicants = $applicants->orderBy('param_skill', $order_dir);
} elseif ($order_by === 'umur') {
$applicants = $applicants->orderBy(function ($applicant) {
return \Carbon\Carbon::parse($applicant->user->birthdate)->age;
}, $order_dir);
} else {
$applicants = $applicants->orderBy('id', $order_dir);
}
$applicants = $applicants->get();
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => $applicants
], 200);
}
public function show_recent_applicant(Request $request, $user_id)
{
$applicants = Applicant::select(
[
'applicants.id',
'applicants.job_id',
'applicants.user_id',
'users.name',
'jobs.name as job_name',
'jobs.recruit_id',
'param_age',
'param_salary',
'param_skill',
'param_distance',
]
)
->join('users', 'users.id', '=', 'user_id')
->join('jobs', 'jobs.id', '=', 'job_id')
->where('jobs.user_id', $user_id);
$order_by = $request->query('order_by', 'id');
$order_dir = $request->query('order_dir', 'desc');
$applicants = $applicants->orderBy($order_by, $order_dir)->get();
$results = [];
foreach ($applicants as $applicant) {
$results[] = [
'applicant' => $applicant,
'score' => 0
];
}
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => $results
], 200);
}
public function show_applicant_wp(Request $request, $id)
{
$applicants = Applicant::select(
[
'applicants.id',
'applicants.job_id',
'applicants.user_id',
'users.name',
'jobs.name as job_name',
'jobs.recruit_id',
'param_age',
'param_salary',
'param_skill',
'param_distance',
]
)
->join('users', 'users.id', '=', 'user_id')
->join('jobs', 'jobs.id', '=', 'job_id')
->where('job_id', $id)->get();
$umur_w = JobParameter::where('job_id', $id)->where('parameter_id', 1)->get()[0]->weight;
$gaji_w = JobParameter::where('job_id', $id)->where('parameter_id', 2)->get()[0]->weight;
$skill_w = JobParameter::where('job_id', $id)->where('parameter_id', 3)->get()[0]->weight;
$lokasi_w = JobParameter::where('job_id', $id)->where('parameter_id', 4)->get()[0]->weight;
$total_w = ($umur_w+$gaji_w+$skill_w+$lokasi_w);
$umur_w = ($umur_w/$total_w)*-1; // Cost
$gaji_w = ($gaji_w/$total_w)*-1; // Cost
$skill_w = ($skill_w/$total_w)*1; // Benefit
$lokasi_w = ($lokasi_w/$total_w)*-1; // Cost
$total_score = 0;
$results = [];
foreach ($applicants as $applicant) {
// Calculate weighted product score
$score = pow($applicant->param_age, $umur_w) *
pow($applicant->param_salary, $gaji_w) *
pow($applicant->param_skill, $skill_w) *
pow($applicant->param_distance, $lokasi_w);
$total_score += $score;
$results[] = [
'applicant' => $applicant,
'score' => $score
];
}
// Calculate vector V (normalized scores)
foreach ($results as &$result) {
$result['score'] = $result['score'] / $total_score;
}
// Sort applicants by score descending
usort($results, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return response()->json([
'error' => false,
'message' => 'Berhasil mengambil data.',
'data' => $results
], 200);
}
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
function haversine($userLocation, $jobLocation) {
$earthRadius = 6371; // Jari-jari bumi dalam kilometer
// Mengambil koordinat dari parameter
$lat1 = $userLocation['lat'];
$lon1 = $userLocation['lng'];
$lat2 = $jobLocation['lat'];
$lon2 = $jobLocation['lng'];
// Menghitung perbedaan dalam radian
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
// Menghitung komponen 'a' dalam rumus Haversine
$a = sin($dLat / 2) * sin($dLat / 2) +
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
sin($dLon / 2) * sin($dLon / 2);
// Menghitung komponen 'c'
$c = 2 * asin(sqrt($a));
// Menghitung dan mengembalikan jarak
return $earthRadius * $c;
}
}