Merge pull request #30 from arieeefajar/fix/assessment-form
fix(assessment-form): function certainty factor calculation
This commit is contained in:
commit
96fbafd505
|
@ -7,6 +7,7 @@
|
||||||
use App\Models\Indicator;
|
use App\Models\Indicator;
|
||||||
use App\Models\Land;
|
use App\Models\Land;
|
||||||
use App\Models\Rule;
|
use App\Models\Rule;
|
||||||
|
use Dotenv\Parser\Value;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
@ -18,12 +19,21 @@ public function index()
|
||||||
$lands = Land::select('id', 'owner')->whereNotIn('id', function ($query) {
|
$lands = Land::select('id', 'owner')->whereNotIn('id', function ($query) {
|
||||||
$query->select('land_id')->from('evaluation');
|
$query->select('land_id')->from('evaluation');
|
||||||
})->orderBy('created_at', 'desc')->get();
|
})->orderBy('created_at', 'desc')->get();
|
||||||
$indicators = Indicator::select('id', 'name')->whereIn('id', function ($query) {
|
$indicators = Indicator::select('id', 'name')->whereHas('rules')->with('rules')->get();
|
||||||
$query->select('indicator_id')->from('rule');
|
|
||||||
})->get();
|
|
||||||
return view('assessment.form', compact('lands', 'indicators'));
|
return view('assessment.form', compact('lands', 'indicators'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function calculateCFc($cf1, $cf2)
|
||||||
|
{
|
||||||
|
if ($cf1 >= 0 && $cf2 >= 0) {
|
||||||
|
return $cf1 + $cf2 * (1 - $cf1);
|
||||||
|
} elseif ($cf1 < 0 && $cf2 < 0) {
|
||||||
|
return $cf1 + $cf2 * (1 + $cf1);
|
||||||
|
} else {
|
||||||
|
return ($cf1 + $cf2) / (1 - min(abs($cf1), abs($cf2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$customMessages = [
|
$customMessages = [
|
||||||
|
@ -40,54 +50,120 @@ public function store(Request $request)
|
||||||
return redirect()->back()->withInput();
|
return redirect()->back()->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
$indicators = $request->except('_token', 'land');
|
$cf_e = $request->except('_token', 'land');
|
||||||
if (count($indicators) == 0) {
|
if (count($cf_e) == 0) {
|
||||||
toast('Harap pilih jawaban untuk nilai indikator', 'error')->position('top-right')->autoclose(3000);
|
toast('Harap pilih jawaban untuk nilai indikator', 'error')->position('top-right')->autoclose(3000);
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules = Rule::whereIn('indicator_id', array_keys($indicators))->get()->keyBy('indicator_id');
|
$cf_h = collect(Rule::whereIn('indicator_id', array_keys($cf_e))
|
||||||
|
->orderByDesc('cf')
|
||||||
|
->get()
|
||||||
|
->unique('indicator_id')
|
||||||
|
->pluck('cf', 'indicator_id')
|
||||||
|
->sortKeys());
|
||||||
|
|
||||||
$cfValue = [];
|
|
||||||
foreach ($indicators as $id => $value) {
|
$cf_he = collect($cf_e)->map(function ($value, $key) use ($cf_h) {
|
||||||
if (isset($rules[$id])) {
|
return [
|
||||||
$rule = $rules[$id];
|
"cf(h,e)" . $key => (float) $value * (float) ($cf_h[$key] ?? 1)
|
||||||
$cfValue[$id] = $rule->mb * $value;
|
];
|
||||||
|
})->collapse();
|
||||||
|
|
||||||
|
$cf_he_array = $cf_he->toArray();
|
||||||
|
|
||||||
|
$cf_combined = array_shift($cf_he_array);
|
||||||
|
|
||||||
|
foreach ($cf_he_array as $cf) {
|
||||||
|
$cf_combined = $this->calculateCFc($cf_combined, $cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cf_pakar = Rule::pluck('cf')->toArray();
|
||||||
|
|
||||||
|
$mean_cf = collect($cf_pakar)->avg();
|
||||||
|
$std_dev_cf = sqrt(collect($cf_pakar)->map(function ($cf) use ($mean_cf) {
|
||||||
|
return pow($cf - $mean_cf, 2);
|
||||||
|
})->avg());
|
||||||
|
|
||||||
|
$threshold_cocok = $mean_cf + $std_dev_cf;
|
||||||
|
$threshold_cocok_bersyarat = $mean_cf - $std_dev_cf;
|
||||||
|
|
||||||
|
if ($cf_combined > $threshold_cocok) {
|
||||||
|
$hasil = 'cocok';
|
||||||
|
} elseif ($cf_combined > $threshold_cocok_bersyarat) {
|
||||||
|
$hasil = 'cocok bersyarat';
|
||||||
} else {
|
} else {
|
||||||
toast("Rule untuk indikator ID {$id} tidak ditemukan.", 'error')->position('top-right')->autoclose(3000);
|
$hasil = 'tidak cocok';
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$cfCombine = array_shift($cfValue);
|
$landName = Land::find($request->land)->owner;
|
||||||
|
// dd($cf_e, $cf_h, $cf_he, $cf_he_array, $cf_combined, $hasil);
|
||||||
foreach ($cfValue as $cf) {
|
|
||||||
$cfCombine = $cfCombine + $cf * (1 - $cfCombine);
|
|
||||||
}
|
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
try {
|
try {
|
||||||
$evaluation = new Evaluation;
|
$evaluation = new Evaluation;
|
||||||
$evaluation->land_id = $request->land;
|
$evaluation->land_id = $request->land;
|
||||||
$evaluation->cf_value = $cfCombine;
|
$evaluation->cf_value = $cf_combined;
|
||||||
$evaluation->user_id = auth()->user()->id;
|
$evaluation->user_id = auth()->user()->id;
|
||||||
$evaluation->save();
|
$evaluation->save();
|
||||||
|
|
||||||
foreach ($indicators as $id => $value) {
|
foreach ($cf_e as $id => $value) {
|
||||||
$evaluationDetail = new EvaluationDetail();
|
$evaluationDetail = new EvaluationDetail;
|
||||||
$evaluationDetail->evaluation_id = $evaluation->id;
|
$evaluationDetail->evaluation_id = $evaluation->id;
|
||||||
$evaluationDetail->indicator_id = $id;
|
$evaluationDetail->indicator_id = $id;
|
||||||
$evaluationDetail->md_value = $value;
|
$evaluationDetail->cf_e = $value;
|
||||||
$evaluationDetail->save();
|
$evaluationDetail->save();
|
||||||
}
|
}
|
||||||
DB::commit();
|
DB::commit();
|
||||||
$presentase = round($cfCombine * 100, 2);
|
$presentase = round($cf_combined * 100, 2);
|
||||||
toast('Data berhasil disimpan', 'success')->position('top-right')->autoclose(3000);
|
toast("Data berhasil disimpan.", "success")->position('top-right')->autoclose(3000);
|
||||||
return redirect()->back()->with('presentase', $presentase);
|
return redirect()->back()->with(['land' => $landName, 'presentase' => $presentase, 'hasil' => $hasil]);
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
toast('Terjadi kesalahan', 'error')->position('top-right')->autoclose(3000);
|
toast($th->getMessage(), 'error')->position('top-right')->autoclose(3000);
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $cfValue = [];
|
||||||
|
// foreach ($cf_e as $id => $value) {
|
||||||
|
// if (isset($rules[$id])) {
|
||||||
|
// $rule = $rules[$id];
|
||||||
|
// $cfValue[$id] = $rule->mb * $value;
|
||||||
|
// } else {
|
||||||
|
// toast("Rule untuk indikator ID {$id} tidak ditemukan.", 'error')->position('top-right')->autoclose(3000);
|
||||||
|
// return redirect()->back();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $cfCombine = array_shift($cfValue);
|
||||||
|
|
||||||
|
// foreach ($cfValue as $cf) {
|
||||||
|
// $cfCombine = $cfCombine + $cf * (1 - $cfCombine);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// DB::beginTransaction();
|
||||||
|
// try {
|
||||||
|
// $evaluation = new Evaluation;
|
||||||
|
// $evaluation->land_id = $request->land;
|
||||||
|
// $evaluation->cf_value = $cfCombine;
|
||||||
|
// $evaluation->user_id = auth()->user()->id;
|
||||||
|
// $evaluation->save();
|
||||||
|
|
||||||
|
// foreach ($indicators as $id => $value) {
|
||||||
|
// $evaluationDetail = new EvaluationDetail();
|
||||||
|
// $evaluationDetail->evaluation_id = $evaluation->id;
|
||||||
|
// $evaluationDetail->indicator_id = $id;
|
||||||
|
// $evaluationDetail->md_value = $value;
|
||||||
|
// $evaluationDetail->save();
|
||||||
|
// }
|
||||||
|
// DB::commit();
|
||||||
|
// $presentase = round($cfCombine * 100, 2);
|
||||||
|
// toast('Data berhasil disimpan', 'success')->position('top-right')->autoclose(3000);
|
||||||
|
// return redirect()->back()->with('presentase', $presentase);
|
||||||
|
// } catch (\Throwable $th) {
|
||||||
|
// DB::rollBack();
|
||||||
|
// toast('Terjadi kesalahan', 'error')->position('top-right')->autoclose(3000);
|
||||||
|
// return redirect()->back();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public function up(): void
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->unsignedBigInteger('evaluation_id');
|
$table->unsignedBigInteger('evaluation_id');
|
||||||
$table->unsignedBigInteger('indicator_id');
|
$table->unsignedBigInteger('indicator_id');
|
||||||
$table->float('md_value');
|
$table->float('cf_e');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -52,15 +52,12 @@
|
||||||
<select name="{{ $indicator->id }}" class="form-control"
|
<select name="{{ $indicator->id }}" class="form-control"
|
||||||
id="{{ $indicator->id }}-field" required>
|
id="{{ $indicator->id }}-field" required>
|
||||||
<option value="" selected disabled>Pilih Jawaban</option>
|
<option value="" selected disabled>Pilih Jawaban</option>
|
||||||
<option value="0">Tidak</option>
|
@foreach ($indicator->rules as $rule)
|
||||||
<option value="0.2">Tidak Tahu</option>
|
<option value="{{ $rule->cf }}">{{ $rule->parameter_type }}</option>
|
||||||
<option value="0.4">Mungkin</option>
|
@endforeach
|
||||||
<option value="0.6">Kemungkinan Besar</option>
|
|
||||||
<option value="0.8">Hampir Pasti</option>
|
|
||||||
<option value="1">Pasti</option>
|
|
||||||
</select>
|
</select>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
Pilih Jawaban
|
Pilih Jawaban {{ $indicator->name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -79,19 +76,25 @@
|
||||||
<form action="">
|
<form action="">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
@if (session('presentase'))
|
@if (session('presentase'))
|
||||||
<h1 class="mb-0 mt-2"><span class="counter-value"
|
|
||||||
data-target="{{ session('presentase') }}">0</span>%
|
|
||||||
</h1>
|
|
||||||
<p class="text-muted mb-0 mt-2">Presentase kelayakan tanah berdasarkan perhitungan
|
<p class="text-muted mb-0 mt-2">Presentase kelayakan tanah berdasarkan perhitungan
|
||||||
Certainty
|
Certainty
|
||||||
Factor.</p>
|
Factor.</p>
|
||||||
|
<h1 class="mb-0 mt-2"><span class="counter-value"
|
||||||
|
data-target="{{ session('presentase') }}">0</span>%
|
||||||
|
</h1>
|
||||||
|
@endif
|
||||||
|
@if (session('hasil') && session('land'))
|
||||||
|
<p class="text-muted mb-0 mt-2">Hasil perhitungan sistem menetapkan lahan
|
||||||
|
<b>"{{ session('land') }}"</b>
|
||||||
|
termasuk
|
||||||
|
dalam kondisi <b>"{{ session('hasil') }}"</b>
|
||||||
|
</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- container-fluid -->
|
<!-- container-fluid -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,7 +107,6 @@
|
||||||
|
|
||||||
<!-- listjs init -->
|
<!-- listjs init -->
|
||||||
<script src="assets/js/pages/form-validation.init.js"></script>
|
<script src="assets/js/pages/form-validation.init.js"></script>
|
||||||
|
|
||||||
<script src="assets/js/pages/customJs/assessment/form.js"></script>
|
<script src="assets/js/pages/customJs/assessment/form.js"></script>
|
||||||
@endpush
|
@endpush
|
||||||
@endsection
|
@endsection
|
||||||
|
|
Loading…
Reference in New Issue