576 lines
19 KiB
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;
|
|
}
|
|
}
|
|
|
|
|