MIF_E31222467/pos-smartphone-fix/app/Http/Controllers/HasilController.php

564 lines
19 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Sample;
use App\Models\Minggu;
use App\Models\Bulan;
use App\Models\Hasil;
use App\Models\Brand;
use App\Models\Training;
use App\Models\Testing;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class HasilController extends Controller
{
// public function index()
// {
// return view('hasiltest');
// }
// public function index(Request $request)
// {
// $brandId = $request->input('brand', 1);
// $data = Hasil::where('brands', $brandId)
// ->orderBy('bulan')
// ->orderBy('minggu')
// ->get();
// $dataPerBulan = [];
// foreach ($data as $item) {
// $bulanNama = $this->getNamaBulan($item->bulan);
// $dataPerBulan[$bulanNama]['minggu_' . $item->minggu] = $item->nilai_prediksi;
// if (!isset($dataPerBulan[$bulanNama]['total']) && $item->total_bulan !== null) {
// $dataPerBulan[$bulanNama]['total'] = $item->total_bulan;
// }
// }
// return view('hasiltest', [
// 'brandId' => $brandId,
// 'dataPerBulan' => $dataPerBulan
// ]);
// }
public function index(Request $request)
{
$brandId = $request->input('brand', 1); // default ke 1 kalau tidak ada
$brands = Brand::all(); // ambil semua brand dari tabel
$data = Hasil::where('brands', $brandId)
->orderByRaw('FIELD(bulan, ' . implode(',', $this->getUrutanBulan()) . ')')
->orderBy('minggu')
->get();
$dataPerBulan = [];
foreach ($data as $item) {
$startMonth = $this->getStartMonth();
$startYear = $this->getStartYear();
// Hitung offset bulan terhadap bulan awal sample
$selisihBulan = ($item->bulan - $startMonth + 12) % 12;
// Tambah 1 tahun dari sample, lalu tambahkan +1 lagi jika bulan lebih kecil dari startMonth (artinya tahun sudah ganti)
$tahunPrediksi = $startYear + 1;
if ($item->bulan < $startMonth) {
$tahunPrediksi++;
}
$bulanNama = $this->getNamaBulan($item->bulan) . ' ' . $tahunPrediksi;
$dataPerBulan[$bulanNama]['minggu_' . $item->minggu] = $item->nilai_prediksi;
// Tetap tampilkan 0 jika total 0
if (!isset($dataPerBulan[$bulanNama]['total']) && $item->total_bulan !== null) {
$dataPerBulan[$bulanNama]['total'] = $item->total_bulan;
}
}
$hasData = $data->isNotEmpty(); // ✅ Tambahkan ini
return view('hasil', [
'brandId' => $brandId,
'brands' => $brands,
'dataPerBulan' => $dataPerBulan,
'hasData' => $hasData, // ✅ Kirim ke view
]);
}
private function getNamaBulan($bulan)
{
$namaBulan = [
1 => 'Januari',
2 => 'Februari',
3 => 'Maret',
4 => 'April',
5 => 'Mei',
6 => 'Juni',
7 => 'Juli',
8 => 'Agustus',
9 => 'September',
10 => 'Oktober',
11 => 'November',
12 => 'Desember',
];
return $namaBulan[$bulan] ?? 'Unknown';
}
private function getStartYear()
{
return session('startYear') ?? now()->year; // fallback ke tahun sekarang kalau tidak ada di session
}
private function getStartMonth()
{
return session('startMonth') ?? now()->month;
}
private function getUrutanBulan()
{
$startMonth = session('startMonth') ?? 1;
$bulan = [];
for ($i = 0; $i < 4; $i++) {
$bulan[] = (($startMonth + $i - 1) % 12) + 1;
}
return $bulan;
}
// public function index(Request $request)
// {
// $brandId = $request->input('brand', 1);
// $hasil = Hasil::where('brands', $brandId)
// ->orderByRaw("FIELD(bulan, 'Januari', 'Februari', 'Maret', 'April')")
// ->orderBy('minggu')
// ->get()
// ->groupBy('bulan');
// return view('hasiltest', compact('hasil', 'brandId'));
// }
// public function proses(Request $request)
// {
// $k = 3;
// $brandId = $request->input('brand', 1);
// // Ambil ID bulan sesuai urutan yang diinginkan
// $bulanIds = Bulan::whereIn('nama', ['Januari', 'Februari', 'Maret', 'April'])
// ->orderByRaw("FIELD(nama, 'Januari', 'Februari', 'Maret', 'April')")
// ->pluck('id')
// ->toArray();
// // Ambil ID minggu (diasumsikan minggu 1-4)
// $mingguIds = Minggu::orderBy('id')->pluck('id')->toArray();
// $trainings = Training::where('brands', $brandId)->get();
// $testings = Testing::where('brands', $brandId)->get();
// $bulanList = ['Januari', 'Februari', 'Maret', 'April']; // Bisa disesuaikan
// $mingguKe = 1;
// $bulanIndex = 0;
// $hasilPrediksi = [];
// // Hapus data lama hasil prediksi dari brand yang sama
// Hasil::where('brands', $brandId)->delete();
// foreach ($testings as $index => $testing) {
// $distances = [];
// foreach ($trainings as $training) {
// $distance = sqrt(
// pow($testing->data_1 - $training->data_1, 2) +
// pow($testing->data_2 - $training->data_2, 2) +
// pow($testing->data_3 - $training->data_3, 2)
// );
// $distances[] = [
// 'distance' => $distance,
// 'target' => $training->target,
// ];
// }
// usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
// $nearest = array_slice($distances, 0, $k);
// $totalTarget = array_sum(array_column($nearest, 'target'));
// $prediksi = round($totalTarget / $k);
// // Simpan ke DB
// $bulanId = $bulanIds[$bulanIndex];
// $mingguId = $mingguIds[$mingguKe - 1];
// Hasil::create([
// 'brands' => $brandId,
// 'bulan' => $bulanId,
// 'minggu' => $mingguId,
// 'nilai_prediksi' => $prediksi,
// ]);
// // Iterasi minggu & bulan
// $mingguKe++;
// if ($mingguKe > 4) {
// $mingguKe = 1;
// $bulanIndex++;
// }
// }
// return redirect()->route('hasiltest.index')->with('success', 'Data prediksi berhasil disimpan.');
// }
// public function proses(Request $request)
// {
// $k = 3;
// $brandIds = Brand::pluck('id'); // Ambil semua ID brand
// // Ambil ID bulan sesuai urutan yang diinginkan
// $bulanIds = Bulan::whereIn('nama', ['Januari', 'Februari', 'Maret', 'April'])
// ->orderByRaw("FIELD(nama, 'Januari', 'Februari', 'Maret', 'April')")
// ->pluck('id')
// ->toArray();
// // Ambil ID minggu (diasumsikan minggu 1-4)
// $mingguIds = Minggu::orderBy('id')->pluck('id')->toArray();
// foreach ($brandIds as $brandId) {
// $trainings = Training::where('brands', $brandId)->get();
// $testings = Testing::where('brands', $brandId)->get();
// $mingguKe = 1;
// $bulanIndex = 0;
// // Hapus hasil lama untuk brand ini
// Hasil::where('brands', $brandId)->delete();
// foreach ($testings as $testing) {
// $distances = [];
// foreach ($trainings as $training) {
// $distance = sqrt(
// pow($testing->data_1 - $training->data_1, 2) +
// pow($testing->data_2 - $training->data_2, 2) +
// pow($testing->data_3 - $training->data_3, 2)
// );
// $distances[] = [
// 'distance' => $distance,
// 'target' => $training->target,
// ];
// }
// usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
// $nearest = array_slice($distances, 0, $k);
// $totalTarget = array_sum(array_column($nearest, 'target'));
// $prediksi = round($totalTarget / $k);
// $bulanId = $bulanIds[$bulanIndex];
// $mingguId = $mingguIds[$mingguKe - 1];
// Hasil::create([
// 'brands' => $brandId,
// 'bulan' => $bulanId,
// 'minggu' => $mingguId,
// 'nilai_prediksi' => $prediksi,
// ]);
// $mingguKe++;
// if ($mingguKe > 4) {
// $mingguKe = 1;
// $bulanIndex++;
// }
// }
// }
// return redirect()->route('hasiltest.index')->with('success', 'Prediksi berhasil dihitung untuk semua brand.');
// }
// public function proses(Request $request)
// {
// $k = 3;
// // Kosongkan tabel hasil terlebih dahulu
// Hasil::truncate();
// for ($brandId = 1; $brandId <= 11; $brandId++) {
// $trainings = Training::where('brands', $brandId)->get();
// $testings = Testing::where('brands', $brandId)->get();
// $hasilPerBulan = [];
// foreach ($testings as $index => $testing) {
// $distances = [];
// foreach ($trainings as $training) {
// $distance = sqrt(
// pow($testing->data_1 - $training->data_1, 2) +
// pow($testing->data_2 - $training->data_2, 2) +
// pow($testing->data_3 - $training->data_3, 2)
// );
// $distances[] = [
// 'distance' => $distance,
// 'target' => $training->target,
// ];
// }
// usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
// $nearest = array_slice($distances, 0, $k);
// $totalTarget = array_sum(array_column($nearest, 'target'));
// $prediksi = round($totalTarget / $k);
// // Hitung bulan dan minggu
// $bulan = intdiv($index, 4) + 1;
// $minggu = ($index % 4) + 1;
// $hasilPerBulan[$bulan][] = [
// 'brand' => $brandId,
// 'bulan' => $bulan,
// 'minggu' => $minggu,
// 'nilai_prediksi' => $prediksi,
// ];
// }
// // Simpan ke DB, hanya 1 baris per bulan yang punya total_bulan
// foreach ($hasilPerBulan as $bulan => $mingguList) {
// $total = array_sum(array_column($mingguList, 'nilai_prediksi'));
// foreach ($mingguList as $i => $item) {
// Hasil::create([
// 'brands' => $item['brand'],
// 'bulan' => $item['bulan'],
// 'minggu' => $item['minggu'],
// 'nilai_prediksi' => $item['nilai_prediksi'],
// 'total_bulan' => $i === 0 ? $total : 0, // Hanya baris pertama tiap bulan
// ]);
// }
// }
// }
// return redirect()->route('hasiltest.index')->with('success', 'Data Training berhasil diambil.');
// }
// public function proses(Request $request)
// {
// $k = 3;
// $allBrands = Brand::all();
// foreach ($allBrands as $brand) {
// $brandId = $brand->id;
// $trainings = Training::where('brands', $brandId)->get();
// $testings = Testing::where('brands', $brandId)->get();
// $hasilPerBulan = [];
// foreach ($testings as $index => $testing) {
// $distances = [];
// foreach ($trainings as $training) {
// $distance = sqrt(
// pow($testing->data_1 - $training->data_1, 2) +
// pow($testing->data_2 - $training->data_2, 2) +
// pow($testing->data_3 - $training->data_3, 2)
// );
// $distances[] = [
// 'distance' => $distance,
// 'target' => $training->target,
// ];
// }
// usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
// $nearest = array_slice($distances, 0, $k);
// $totalTarget = array_sum(array_column($nearest, 'target'));
// $prediksi = round($totalTarget / $k);
// $bulan = intdiv($index, 4) + 1;
// $minggu = ($index % 4) + 1;
// $hasilPerBulan[$bulan][] = [
// 'brand' => $brandId,
// 'bulan' => $bulan,
// 'minggu' => $minggu,
// 'nilai_prediksi' => $prediksi,
// ];
// }
// foreach ($hasilPerBulan as $bulan => $mingguList) {
// $total = array_sum(array_column($mingguList, 'nilai_prediksi'));
// foreach ($mingguList as $i => $item) {
// Hasil::create([
// 'brands' => $item['brand'],
// 'bulan' => $item['bulan'],
// 'minggu' => $item['minggu'],
// 'nilai_prediksi' => $item['nilai_prediksi'],
// 'total_bulan' => $i === 0 ? $total : 0,
// ]);
// }
// }
// }
// return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
// }
// public function proses(Request $request)
// {
// $k = 3;
// $allBrands = Brand::all();
// foreach ($allBrands as $brand) {
// $brandId = $brand->id;
// $trainings = Training::where('brands', $brandId)->get();
// $testings = Testing::where('brands', $brandId)->get();
// $hasilPerBulan = [];
// foreach ($testings as $index => $testing) {
// $distances = [];
// foreach ($trainings as $training) {
// $distance = sqrt(pow($testing->data_1 - $training->data_1, 2) + pow($testing->data_2 - $training->data_2, 2) + pow($testing->data_3 - $training->data_3, 2));
// $distances[] = [
// 'distance' => $distance,
// 'target' => $training->target,
// ];
// }
// usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
// $nearest = array_slice($distances, 0, $k);
// $totalTarget = array_sum(array_column($nearest, 'target'));
// $prediksi = round($totalTarget / $k);
// // Ambil bulan dari sample yang sesuai
// $sample = Sample::find($testing->id);
// $bulan = $sample ? $sample->bulan : 1;
// $minggu = ($index % 4) + 1;
// $hasilPerBulan[$bulan][] = [
// 'brand' => $brandId,
// 'bulan' => $bulan,
// 'minggu' => $minggu,
// 'nilai_prediksi' => $prediksi,
// ];
// }
// foreach ($hasilPerBulan as $bulan => $mingguList) {
// $total = array_sum(array_column($mingguList, 'nilai_prediksi'));
// foreach ($mingguList as $i => $item) {
// Hasil::create([
// 'brands' => $item['brand'],
// 'bulan' => $item['bulan'],
// 'minggu' => $item['minggu'],
// 'nilai_prediksi' => $item['nilai_prediksi'],
// 'total_bulan' => $i === 0 ? $total : 0,
// ]);
// }
// }
// }
// return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
// }
public function proses(Request $request)
{
$k = 3;
$allBrands = Brand::all();
// Ambil bulan dan minggu dari brand pertama sebagai acuan
$firstBrandId = $allBrands->first()->id;
$referenceTesting = Testing::where('brands', $firstBrandId)->get();
$bulanMingguMap = [];
foreach ($referenceTesting as $index => $test) {
$sample = Sample::find($test->id);
$bulan = $sample ? $sample->bulan : 1;
$minggu = ($index % 4) + 1;
$bulanMingguMap[$index] = [
'bulan' => $bulan,
'minggu' => $minggu,
];
}
// Proses untuk semua brand dengan acuan bulan/minggu
foreach ($allBrands as $brand) {
$brandId = $brand->id;
$trainings = Training::where('brands', $brandId)->get();
$testings = Testing::where('brands', $brandId)->get();
$hasilPerBulan = [];
foreach ($testings as $index => $testing) {
$distances = [];
foreach ($trainings as $training) {
$distance = sqrt(pow($testing->data_1 - $training->data_1, 2) + pow($testing->data_2 - $training->data_2, 2) + pow($testing->data_3 - $training->data_3, 2));
$distances[] = [
'distance' => $distance,
'target' => $training->target,
];
}
usort($distances, fn($a, $b) => $a['distance'] <=> $b['distance']);
$nearest = array_slice($distances, 0, $k);
$totalTarget = array_sum(array_column($nearest, 'target'));
$prediksi = round($totalTarget / $k);
$bulan = $bulanMingguMap[$index]['bulan'];
$minggu = $bulanMingguMap[$index]['minggu'];
$hasilPerBulan[$bulan][] = [
'brand' => $brandId,
'bulan' => $bulan,
'minggu' => $minggu,
'nilai_prediksi' => $prediksi,
];
}
foreach ($hasilPerBulan as $bulan => $mingguList) {
$total = array_sum(array_column($mingguList, 'nilai_prediksi'));
foreach ($mingguList as $i => $item) {
Hasil::create([
'brands' => $item['brand'],
'bulan' => $item['bulan'],
'minggu' => $item['minggu'],
'nilai_prediksi' => $item['nilai_prediksi'],
'total_bulan' => $i === 0 ? $total : 0,
]);
}
}
}
return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil diambil.');
}
public function reset()
{
DB::table('hasil')->truncate();
return redirect()->route('hasil.index')->with('success', 'Hasil Prediksi berhasil direset.');
}
}