TIF_E41211320/app/Http/Controllers/Api/V1/ProfileMatching/ProfileMatchingController.php

221 lines
7.1 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1\ProfileMatching;
use App\Http\Controllers\Controller;
use App\Http\Requests\ProfileMatching\ProfileMatchingRequest;
use App\Models\Alternatif;
use App\Models\Aspek;
use App\Models\Kriteria;
use App\Models\ProfileMethod;
use App\Models\Subkriteria;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class ProfileMatchingController extends Controller
{
public function handleProfileMatching(ProfileMatchingRequest $request)
{
try {
$validated = $request->validated();
$data['judul'] = $request->input('judul');
$data['deskripsi'] = $request->input('deskripsi');
$selectedKriteria = $request->input('kriteria', []);
$selectedAlternatif = $request->input('alternatif', []);
if (empty($selectedKriteria) || empty($selectedAlternatif)) {
return back()->withErrors('Kriteria dan alternatif harus dipilih.')->withInput();
}
Log::info('Selected Kriteria:', ['data' => $selectedKriteria]);
Log::info('Selected Alternatif:', ['data' => $selectedAlternatif]);
$data['resultsGAP'] = $this->gapProfil($selectedAlternatif, $selectedKriteria);
$data['normalizedGAP'] = $this->normalizeGAP($data['resultsGAP']);
$data['factorValue'] = $this->factorValue($data['normalizedGAP']);
$data['totalValue'] = $this->totalValue($data['factorValue']);
$data['ranking'] = $this->rankAlternatif($data['totalValue']);
$data['data_aspek'] = Aspek::all();
$data['data_kriteria'] = Kriteria::all();
if (empty($data['resultsGAP']) || empty($data['ranking'])) {
return back()->withErrors('Terjadi kesalahan saat memproses data.')->withInput();
}
// dd($data);
return view('profile-matching.result', $data);
} catch (\Exception $e) {
Log::error('Error in Profile Matching:', ['message' => $e->getMessage()]);
return response()->json(['error' => 'Terjadi kesalahan saat memproses data: ' . $e->getMessage()], 500);
}
}
private function gapProfil($alternatif, $kriteria)
{
$resultsGAP = [];
$gapValues = [];
$dosenProfile = ProfileMethod::with('kriteria', 'subkriteria')->whereIn('id_alternatif', $alternatif)->get();
foreach ($dosenProfile as $dosen) {
$dosenSubkriteria = $dosen->subkriteria;
$dosenKriteria = $dosen->kriteria;
foreach ($kriteria as $key => $subkriteriaId) {
$idealValue = Subkriteria::with('kriteria')->find($subkriteriaId);
$idealKriteria = $idealValue->kriteria;
if ($dosenKriteria->id_kriteria == $idealKriteria->id_kriteria) {
$gapValues[$idealValue->id_kriteria] = $dosenSubkriteria->nilai - $idealValue->nilai;
}
}
$resultsGAP[$dosen->id_alternatif] = $gapValues;
}
Log::info('Ideal Value:', ['data' => $idealValue]);
Log::info('GAP Values:', ['dosenId' => $dosen->id_alternatif, 'gapValues' => $gapValues]);
return $resultsGAP;
}
private function normalizeGAP($resultsGAP)
{
$normalizedGAP = [];
$normalizedValues = [];
$conversionTable = [
0 => 5,
1 => 4.5,
-1 => 4,
2 => 3.5,
-2 => 3,
3 => 2.5,
-3 => 2,
4 => 1.5,
-4 => 1
];
foreach ($resultsGAP as $dosenId => $gapValues) {
foreach ($gapValues as $key => $gap) {
$normalizedValues[$key] = $conversionTable[$gap] ?? 1;
}
$normalizedGAP[$dosenId] = $normalizedValues;
}
return $normalizedGAP;
}
private function factorValue($normalizedGAP) {
$resultsFactor = [];
foreach ($normalizedGAP as $dosenId => $gapValues) {
$dataAspek = Aspek::all();
$aspek = [];
foreach ($dataAspek as $aspekValue) {
$aspekId = $aspekValue->id_aspek;
$coreValues = 0;
$secondaryValues = 0;
$coreCount = 0;
$secondaryCount = 0;
$factorValue = [];
foreach ($gapValues as $kriteria => $values) {
$factor = Kriteria::find($kriteria);
if ($factor->tipe == 'Core Factor') {
if ($aspekId == $factor->id_aspek) {
$coreValues += $values;
$coreCount++;
}
} else {
if ($aspekId == $factor->id_aspek) {
$secondaryValues += $values;
$secondaryCount++;
}
}
}
if ($coreCount > 0) {
$factorValue['NCF'] = $coreValues / $coreCount;
}
if ($secondaryCount > 0) {
$factorValue['NSF'] = $secondaryValues / $secondaryCount;
}
$aspek[$aspekId] = $factorValue;
}
$resultsFactor[$dosenId] = $aspek;
}
return $resultsFactor;
}
private function totalValue($factorValue)
{
$totalValues = [];
$aspek = [];
$totalValueFactor = [];
$bobotCF = 60;
$bobotSF = 40;
foreach ($factorValue as $dosenId => $value) {
foreach ($value as $aspekId => $values) {
$value = [];
foreach ($values as $tipeValue => $valueFactor) {
if ($tipeValue == 'NCF') {
$value[] = $valueFactor * $bobotCF / 100;
} else {
$value[] = $valueFactor * $bobotSF / 100;
}
}
$totalValueFactor = array_sum($value);
$aspek[$aspekId] = $totalValueFactor;
}
$totalValues[$dosenId] = $aspek;
}
return $totalValues;
}
private function rankAlternatif($totalValues)
{
$rankedResults = [];
foreach ($totalValues as $dosenId => $totalValue) {
$ha = 0;
foreach ($totalValue as $aspekId => $value) {
$bobotAspek = Aspek::where('id_aspek', $aspekId)->pluck('persentase')->first();
if ($bobotAspek) {
$ha += $value * ($bobotAspek / 100);
}
}
$alternatif = Alternatif::where('id_alternatif', $dosenId)->first();
$rankedResults[] = [
'dosenId' => $alternatif->id_alternatif,
'dosenName' => $alternatif->name,
'hasilAkhir' => $ha,
];
}
usort($rankedResults, function ($a, $b) {
return $b['hasilAkhir'] <=> $a['hasilAkhir'];
});
foreach ($rankedResults as $index => &$result) {
$result['rank'] = $index + 1;
}
return $rankedResults;
}
}