MIF_E31222541/app/Http/Controllers/Website/VillageAlternatifController...

530 lines
24 KiB
PHP

<?php
namespace App\Http\Controllers\Website;
use App\Http\Controllers\Controller;
use App\Models\CriteriaData;
use App\Models\HeightVillage;
use App\Models\PhVillage;
use App\Models\PreferenceResultPlant;
use App\Models\PreferenceResultVillage;
use App\Models\SubDistrict;
use App\Models\Village;
use App\Models\VillageAlternatif;
use App\Models\WeatherVillage;
use Illuminate\Http\Request;
class VillageAlternatifController extends Controller
{
public function index()
{
// mengambil list tahun
$listResultPreference = VillageAlternatif::all();
$years = array_unique(array_column($listResultPreference->toArray(), 'year'));
sort($years);
$listSubDistrict = SubDistrict::all();
$criterias = CriteriaData::all();
return view('website.app.village-alternatif', compact('listSubDistrict', 'criterias', 'years'));
}
public function getVillage($id)
{
$village = Village::where('sub_district_id', $id)->get();
return response()->json([
'village' => $village
]);
}
public function addAlternatifVillage(Request $request)
{
$criterias = CriteriaData::all();
$villageId = $request->input('villageId');
$month = $request->input('month');
$year = $request->input('year');
// mengecek apakah sudah tersedia atau belum
$villageAlternatifs = VillageAlternatif::where('village_id', $villageId)
->where('month', $month)
->where('year', $year)
->get();
if (count($villageAlternatifs) == 0) {
foreach ($criterias as $key => $value) {
VillageAlternatif::create([
'village_id' => $villageId,
'month' => $month,
'year' => $year,
'criteria_id' => $value->id,
'value_alternatif' => $request->input(str_replace(' ', '_', $value->criteria)),
]);
}
toast('Data alternatif desa berhasil ditambahkan!', 'success');
return redirect()->back();
} else {
toast('Gagal, Data alternatif desa bulan ' . $month . ' tahun ' . $year . ' sudah tersedia!', 'error');
return redirect()->back();
}
}
public function updateAlternatifVillage($month, $years, $subDistrictId)
{
$villageBySubDistrictId = Village::select('id', 'sub_district_id', 'village', 'latitude', 'longitude')
->where('sub_district_id', $subDistrictId)->get();
try {
foreach ($villageBySubDistrictId as $village) {
$weatherVillage = WeatherVillage::where('village_id', $village['id'])
->where('month', $month)
->where('year', $years)
->get();
$heightVillage = HeightVillage::where('village_id', $village['id'])
->where('year', $years)
->first();
$phVillage = PhVillage::where('village_id', $village['id'])
->first();
if ($weatherVillage->isEmpty()) {
toast('Belum Lengkap dan cek kembali, download data cuaca tahunan terlebih dahulu !!', 'error');
} else if (is_null($heightVillage)) {
toast('Belum Lengkap dan cek kembali, download data ketinggian tahunan terlebih dahulu !!', 'error');
} else if (is_null($phVillage)) {
toast('Belum Lengkap dan cek kembali, download data pH tahunan terlebih dahulu !!', 'error');
}
if ($heightVillage['height']) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weatherVillage[0]['month'],
'year' => $weatherVillage[0]['year'],
'criteria_id' => '1'
],
[
'value_alternatif' => $heightVillage['height'],
]
);
}
foreach ($weatherVillage as $key => $weather) {
if ($weather["allsky_sfc_sw_dwn"]) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weather['month'],
'year' => $weather['year'],
'criteria_id' => '2'
],
[
'value_alternatif' => $weather["allsky_sfc_sw_dwn"],
]
);
}
if ($weather["prectotcorr"]) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weather['month'],
'year' => $weather['year'],
'criteria_id' => '3'
],
[
'value_alternatif' => $weather["prectotcorr"],
]
);
}
if ($weather["rh2m"]) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weather['month'],
'year' => $weather['year'],
'criteria_id' => '4'
],
[
'value_alternatif' => $weather["rh2m"],
]
);
}
if ($weather["t2m"]) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weather['month'],
'year' => $weather['year'],
'criteria_id' => '5'
],
[
'value_alternatif' => $weather["t2m"],
]
);
}
if ($weather["ws2m"]) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weather['month'],
'year' => $weather['year'],
'criteria_id' => '6'
],
[
'value_alternatif' => $weather["ws2m"],
]
);
}
}
if ($phVillage['meter_0_5']) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weatherVillage[0]['month'],
'year' => $weatherVillage[0]['year'],
'criteria_id' => '7'
],
[
'value_alternatif' => $phVillage['meter_0_5'],
]
);
} else if ($phVillage['meter_0_5'] == 0) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $village['id'],
'month' => $weatherVillage[0]['month'],
'year' => $weatherVillage[0]['year'],
'criteria_id' => '7'
],
[
'value_alternatif' => '5.5',
]
);
}
}
return response()->json(['success' => true, 'message' => `Data alternatif desa $month,$years berhasil diperbarui!`]);
} catch (\Exception $e) {
// Tangani kesalahan dan tampilkan pesan error
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 500);
}
}
public function deleteAlternatifVillage($id, $month, $year)
{
// hapus referensi alternatif
$villageAlternatif = VillageAlternatif::where('village_id', '=', $id)->where('month', $month)->where('year', $year)->get();
foreach ($villageAlternatif as $value) {
$value->delete();
}
// // hapus pada relasi preference result sub district
$preferenceResultVillage = PreferenceResultVillage::where('village_id', '=', $id)->where('month', $month)->where('year', $year)->get();
foreach ($preferenceResultVillage as $value) {
$value->delete();
}
toast('Data alternatif desa berhasil dihapus', 'success');
return redirect()->back();
}
public function updateAlternatifByVillage(Request $request)
{
$criterias = CriteriaData::all();
$villageId = $request->input('villageId');
$month = $request->input('month');
$year = $request->input('year');
foreach ($criterias as $key => $value) {
VillageAlternatif::updateOrCreate(
[
'village_id' => $villageId,
'criteria_id' => $value->id,
'month' => $month,
'year' => $year,
],
[
'value_alternatif' => $request->input(str_replace(' ', '_', $value->criteria))
]
);
}
toast('Data alternatif desa berhasil diubah!', 'success');
return redirect()->back();
}
public function getAlternatifVillage($month, $years, $subDistrictId)
{
$listAlternatifVillage = VillageAlternatif::select(
'village_alternatifs.id as village_alternatifs_id',
'village_alternatifs.village_id as va_village_id',
'village_alternatifs.criteria_id as va_criteria_id',
'village_alternatifs.value_alternatif',
'village_alternatifs.month',
'village_alternatifs.year',
'village.id as village_id',
'village.village',
'village.sub_district_id',
'criteria_data.id as criteria_data_id',
'criteria_data.criteria',
'criteria_data.bobot',
'criteria_data.status'
)
->join('village', 'village.id', '=', 'village_alternatifs.village_id')
->join('criteria_data', 'criteria_data.id', '=', 'village_alternatifs.criteria_id')
->where('village_alternatifs.month', '=', $month)
->where('village_alternatifs.year', '=', $years)
->where('village.sub_district_id', '=', $subDistrictId)
->get();
$listCriteria = CriteriaData::all();
// apakah ada list desa
$villageBySubDistrictId = Village::where('sub_district_id', $subDistrictId)->get();
if (count($villageBySubDistrictId) > 0) {
if (count($listAlternatifVillage) != 0) {
$groupByVillage = $listAlternatifVillage->groupBy('va_village_id')->map(function ($villageData) {
$village = $villageData->first();
return [
'village_id' => $village->village_id,
'village' => $village->village,
'month' => $village->month,
'year' => $village->year,
'criteria' => $villageData->map(function ($item) {
return [
'criteria_id' => $item->criteria_data_id,
'criteria' => $item->criteria,
'value_alternatif' => $item->value_alternatif,
'status' => $item->status,
'bobot' => $item->bobot
];
})->toArray()
];
});
// mengecek apakah jumlah pada setiap criteria sama
$valueFirstIndex = array_key_first($groupByVillage->toArray());
$firstGroupByVillage = count($groupByVillage[$valueFirstIndex]['criteria']);
$checkGroupByVillage = true;
foreach ($groupByVillage as $village) {
if (count($village['criteria']) !== $firstGroupByVillage) {
$checkGroupByVillage = false;
break;
}
}
if ($checkGroupByVillage == false) {
return response()->json([
'listCriterias' => $listCriteria,
'groupByVillage' => $groupByVillage,
'message' => 'fail'
]);
} else {
// pembagi matriks ternomalisasi
$countCriteria = count($groupByVillage[$valueFirstIndex]['criteria']);
$pembagiMatriksTernomalisasi = [];
for ($i = 0; $i < $countCriteria; $i++) {
$sumKuadrat = 0;
foreach ($groupByVillage as $item) {
$sumKuadrat += pow($item["criteria"][$i]["value_alternatif"], 2);
}
// Hitung akar dari jumlah kuadrat
$pembagiMatriksTernomalisasi[$i] = round((sqrt($sumKuadrat)), 5);
}
// data matriks ternomalisasi desa
$matriksTernomalisasiVillage = [];
foreach ($groupByVillage as $item) {
$valueBaru = [];
foreach ($item['criteria'] as $index => $value) {
$value['value_alternatif'] = round(($value['value_alternatif'] / $pembagiMatriksTernomalisasi[$index]), 5);
$valueBaru[] = [
'criteria_id' => $value['criteria_id'],
'criteria' => $value['criteria'],
'value_alternatif' => $value['value_alternatif'],
'status' => $value['status'],
'bobot' => $value['bobot']
];
}
$matriksTernomalisasiVillage[] = [
'village_id' => $item['village_id'],
'village' => $item['village'],
'criteria' => $valueBaru
];
}
// data matriks ternomalisasi terbobot kecamatan
$ternomalisasiTerbobotVillage = [];
foreach ($groupByVillage as $item) {
$valueBaru = [];
foreach ($item['criteria'] as $index => $value) {
$value['value_alternatif'] = round(($value['value_alternatif'] / $pembagiMatriksTernomalisasi[$index]), 5);
$valueBaru[] = [
'criteria_id' => $value['criteria_id'],
'criteria' => $value['criteria'],
'value_alternatif' => round(($value['value_alternatif'] * $value['bobot']), 5),
'status' => $value['status'],
'bobot' => $value['bobot']
];
}
$ternomalisasiTerbobotVillage[] = [
'village_id' => $item['village_id'],
'village' => $item['village'],
'criteria' => $valueBaru
];
}
// data solusi ideal positif dan negatif
// 1. pengumpulan hasil data terbobot berdasarkan criteria
$criteria_values = [];
foreach ($ternomalisasiTerbobotVillage as $ternomalisasi) {
foreach ($ternomalisasi['criteria'] as $index => $criteria) {
$criteria_values[$index]['criteria_id'] = $criteria['criteria_id'];
$criteria_values[$index]['criteria'] = $criteria['criteria'];
$criteria_values[$index]['status'] = $criteria['status'];
$criteria_values[$index]['values'][] = $criteria['value_alternatif'];
}
}
// 2. menentukan ideal positif dan ideal negatif
$ideal_positif = [];
$ideal_negatif = [];
foreach ($criteria_values as $index => $criteria) {
if ($criteria['status'] === "benefit") {
$ideal_positif[$index] = max($criteria['values']);
$ideal_negatif[$index] = min($criteria['values']);
} else {
$ideal_positif[$index] = min($criteria['values']);
$ideal_negatif[$index] = max($criteria['values']);
}
}
// solusi ideal terbobot desa
$determinanVillage = [];
foreach ($ternomalisasiTerbobotVillage as $ternomalisasi) {
$jumlahDeterminanPositif = 0;
$jumlahDeterminanNegatif = 0;
foreach ($ternomalisasi['criteria'] as $index => $criteria) {
$jumlahDeterminanPositif += pow(($criteria['value_alternatif'] - $ideal_positif[$index]), 2);
$jumlahDeterminanNegatif += pow(($criteria['value_alternatif'] - $ideal_negatif[$index]), 2);
}
$determinanVillage[] = [
'id' => $ternomalisasi['village_id'],
'village' => $ternomalisasi['village'],
'determinanPositif' => round((sqrt($jumlahDeterminanPositif)), 5),
'determinanNegatif' => round((sqrt($jumlahDeterminanNegatif)), 5)
];
}
// menyimpan hasil preferensi setiap desa
if (count($determinanVillage) != 0 && count($determinanVillage) != 1) {
foreach ($determinanVillage as $preference) {
PreferenceResultVillage::updateOrCreate(
[
'village_id' => $preference['id'],
'month' => $month,
'year' => $years,
],
[
'value_preference' => round($preference['determinanNegatif'] / ($preference['determinanNegatif'] + $preference['determinanPositif']), 5),
'plant_name' => ''
]
);
}
}
// ambil hasil preferensi village di database
$preferenceResultVillage = PreferenceResultVillage::select(
'preference_result_villages.id',
'preference_result_villages.village_id as prv_village_id',
'preference_result_villages.value_preference',
'preference_result_villages.plant_name',
'preference_result_villages.month',
'preference_result_villages.year',
'village.id as v_id',
'village.village'
)
->join('village', 'village.id', '=', 'preference_result_villages.village_id')
->where('preference_result_villages.month', '=', $month)
->where('preference_result_villages.year', '=', $years)
->where('village.sub_district_id', '=', $subDistrictId)
->get();
$preferenceResultPlant = PreferenceResultPlant::select(
'preference_result_plants.id',
'preference_result_plants.plant_id as prp_plant_id',
'preference_result_plants.value_preference',
'plants.id as pl_id',
'plants.plant'
)
->join('plants', 'plants.id', '=', 'preference_result_plants.plant_id')
->get();
$prVillageArray = [];
$prPlantArray = [];
$resultPlantByVillage = [];
if (count($preferenceResultVillage) != 0 && count($preferenceResultPlant) != 0) {
foreach ($preferenceResultVillage as $prVillage) {
$prVillageArray[$prVillage['village']] = $prVillage['value_preference'];
}
foreach ($preferenceResultPlant as $prPlant) {
$prPlantArray[$prPlant['plant']] = $prPlant['value_preference'];
}
foreach ($prVillageArray as $village => $valuePreferenceVillage) {
$PlantByChoice = collect($prPlantArray)
->sortBy(fn($valuePreferencePlant) => abs($valuePreferencePlant - $valuePreferenceVillage))
->keys()
->first();
$resultPlantByVillage[$village] = $PlantByChoice;
}
// menambah atau update data reference kecamatan (tanaman)
foreach ($preferenceResultVillage as $prVillage) {
PreferenceResultVillage::updateOrCreate(
[
'village_id' => $prVillage['prv_village_id'],
'month' => $month,
'year' => $years,
],
[
'value_preference' => $prVillage['value_preference'],
'plant_name' => $resultPlantByVillage[$prVillage['village']]
]
);
}
}
return response()->json([
'listCriterias' => $listCriteria,
'groupByVillage' => $groupByVillage,
'pembagiMatriksTernomalisasi' => $pembagiMatriksTernomalisasi,
'matriksTernomalisasiVillage' => $matriksTernomalisasiVillage,
'ternomalisasiTerbobotVillage' => $ternomalisasiTerbobotVillage,
'solusiIdealPositif' => $ideal_positif,
'solusiIdealNegatif' => $ideal_negatif,
'determinanVillage' => $determinanVillage,
'resultPlantByVillage' => $resultPlantByVillage
]);
}
}
} else {
return response()->json([
'message' => "Data tidak ditemukan"
]);
}
}
}