Update Status kelengkapan data
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use App\Enums\StatusDataPetani;
|
||||
use App\Models\Pertanian\Petani;
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* Data petani yang sudah ditandai "Lengkap" lalu diubah/ditambah/dihapus
|
||||
* otomatis kembali ke "Draf", supaya enumerator menandai lengkap lagi setelah selesai.
|
||||
*
|
||||
* Dipasang di semua model yang menyimpan data profil petani (web maupun API).
|
||||
* Model yang tidak punya kolom petani_id meng-override petaniIdUntukStatus().
|
||||
*/
|
||||
trait KembalikanStatusPetaniKeDraf
|
||||
{
|
||||
// Kolom otomatis/audit yang tidak dihitung sebagai perubahan data.
|
||||
private static array $kolomBukanPerubahanData = [
|
||||
'created_at', 'updated_at', 'deleted_at', 'created_by', 'updated_by', 'deleted_by', 'status',
|
||||
];
|
||||
|
||||
public static function bootKembalikanStatusPetaniKeDraf(): void
|
||||
{
|
||||
static::saved(function ($model) {
|
||||
$kolomBerubah = array_diff(array_keys($model->getChanges()), self::$kolomBukanPerubahanData);
|
||||
|
||||
if ($model->wasRecentlyCreated || $kolomBerubah) {
|
||||
$model->kembalikanStatusPetaniKeDraf();
|
||||
}
|
||||
});
|
||||
|
||||
static::deleted(fn ($model) => $model->kembalikanStatusPetaniKeDraf());
|
||||
}
|
||||
|
||||
protected function petaniIdUntukStatus(): ?int
|
||||
{
|
||||
return $this->petani_id;
|
||||
}
|
||||
|
||||
public function kembalikanStatusPetaniKeDraf(): void
|
||||
{
|
||||
$petaniId = $this->petaniIdUntukStatus();
|
||||
if (! $petaniId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Satu simpan bisa memicu ratusan baris (mis. sinkron jenis hama ke semua tanaman).
|
||||
// Cukup sekali per petani per request: setelah dicek, status pasti bukan "Lengkap" lagi.
|
||||
self::ingatPerRequest('status_petani.dicek', $petaniId, function () use ($petaniId) {
|
||||
// Query langsung (tanpa event model) supaya tidak memicu hook lain / berulang.
|
||||
$diubah = Petani::withoutGlobalScopes()
|
||||
->whereKey($petaniId)
|
||||
->where('status', StatusDataPetani::LENGKAP->value)
|
||||
->update(['status' => StatusDataPetani::DRAFT->value]);
|
||||
|
||||
if ($diubah && request()->hasSession()) {
|
||||
request()->session()->flash('status_petani_info', 'Data petani diubah, status kembali ke Draf. Tandai lengkap lagi setelah selesai.');
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpan hasil $ambil() selama satu request web, per $kunci + $id.
|
||||
* Di console/queue tidak disimpan (proses berjalan lama, data bisa berubah antar-job).
|
||||
*/
|
||||
protected static function ingatPerRequest(string $kunci, int|string|null $id, Closure $ambil): mixed
|
||||
{
|
||||
if ($id === null || app()->runningInConsole()) {
|
||||
return $ambil();
|
||||
}
|
||||
|
||||
$bag = request()->attributes;
|
||||
$cache = $bag->get($kunci, []);
|
||||
|
||||
if (! array_key_exists($id, $cache)) {
|
||||
$cache[$id] = $ambil();
|
||||
$bag->set($kunci, $cache);
|
||||
}
|
||||
|
||||
return $cache[$id];
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -15,7 +16,7 @@ use App\Enums\AksesPasar\SkorKesadaranPremium;
|
||||
|
||||
class AksesPasar extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'akses_pasar';
|
||||
|
||||
@@ -77,7 +78,7 @@ class AksesPasar extends Model
|
||||
$skor->update([
|
||||
'skor_d6_k1_6_pengalaman_menjual_ke_saluran_berbeda' => $aksesPasar->skor_pengalaman,
|
||||
'skor_d6_k4_1_kesadaran_akses_pasar_premium' => $aksesPasar->skor_kesadaran_premium,
|
||||
'skor_d6_k5_1_hambatan_mutu' => $aksesPasar->skor_kepercayaan_responden
|
||||
// skor_d6_k5_1_hambatan_mutu diisi dari SurveyPanen (tingkat hasil panen ditolak).
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\User;
|
||||
use App\Models\Pertanian\Petani;
|
||||
|
||||
class HargaJualPanen extends Model
|
||||
{
|
||||
use KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'harga_jual_panen';
|
||||
|
||||
protected $fillable = [
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Models\Wilayah\DesaKelurahan;
|
||||
@@ -22,7 +23,7 @@ use App\Models\Pertanian\Petani;
|
||||
|
||||
class Lahan extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'map_lahan';
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PendapatanKomoditas extends Model
|
||||
{
|
||||
use KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'pendapatan_komoditas';
|
||||
|
||||
protected $fillable = [
|
||||
@@ -29,4 +32,11 @@ class PendapatanKomoditas extends Model
|
||||
{
|
||||
return $this->belongsTo(SosialEkonomi::class, 'sosial_ekonomi_id');
|
||||
}
|
||||
|
||||
// Untuk trait KembalikanStatusPetaniKeDraf: petani diambil dari data sosial ekonomi.
|
||||
protected function petaniIdUntukStatus(): ?int
|
||||
{
|
||||
return self::ingatPerRequest('status_petani.sosial_ekonomi', $this->sosial_ekonomi_id,
|
||||
fn () => SosialEkonomi::withoutGlobalScopes()->whereKey($this->sosial_ekonomi_id)->value('petani_id'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PendapatanLuarPertanian extends Model
|
||||
{
|
||||
use KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'pendapatan_luar_pertanian';
|
||||
|
||||
protected $fillable = [
|
||||
@@ -27,4 +30,11 @@ class PendapatanLuarPertanian extends Model
|
||||
{
|
||||
return $this->belongsTo(SosialEkonomi::class, 'sosial_ekonomi_id');
|
||||
}
|
||||
|
||||
// Untuk trait KembalikanStatusPetaniKeDraf: petani diambil dari data sosial ekonomi.
|
||||
protected function petaniIdUntukStatus(): ?int
|
||||
{
|
||||
return self::ingatPerRequest('status_petani.sosial_ekonomi', $this->sosial_ekonomi_id,
|
||||
fn () => SosialEkonomi::withoutGlobalScopes()->whereKey($this->sosial_ekonomi_id)->value('petani_id'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use App\Enums\Pendidikan;
|
||||
use App\Enums\Pernikahan;
|
||||
use App\Enums\Role;
|
||||
@@ -30,7 +31,7 @@ use Illuminate\Support\Str;
|
||||
|
||||
class Petani extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'petani';
|
||||
|
||||
@@ -420,4 +421,10 @@ class Petani extends Model
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
// Untuk trait KembalikanStatusPetaniKeDraf: petani ini sendiri.
|
||||
protected function petaniIdUntukStatus(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@@ -18,7 +19,7 @@ use App\Models\Pertanian\Lahan;
|
||||
|
||||
class PraktikBudidaya extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'praktik_budidaya';
|
||||
|
||||
@@ -101,27 +102,11 @@ class PraktikBudidaya extends Model
|
||||
$jenisHama = $praktikBudidaya->jenis_hama ?? [];
|
||||
$jenisPenyakit = $praktikBudidaya->jenis_penyakit ?? [];
|
||||
|
||||
if (Schema::hasColumn((new Lahan)->getTable(), 'jenis_hama')
|
||||
&& Schema::hasColumn((new Lahan)->getTable(), 'jenis_penyakit')) {
|
||||
Lahan::where('petani_id', $praktikBudidaya->petani_id)->get()->each(function (Lahan $lahan) use ($jenisHama, $jenisPenyakit, $praktikBudidaya) {
|
||||
$lahan->update([
|
||||
'jenis_hama' => $jenisHama,
|
||||
'jenis_penyakit' => $jenisPenyakit,
|
||||
'updated_by' => $praktikBudidaya->updated_by,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
if (Schema::hasColumn((new Tanaman)->getTable(), 'jenis_hama')
|
||||
&& Schema::hasColumn((new Tanaman)->getTable(), 'jenis_penyakit')) {
|
||||
Tanaman::where('petani_id', $praktikBudidaya->petani_id)->get()->each(function (Tanaman $tanaman) use ($jenisHama, $jenisPenyakit, $praktikBudidaya) {
|
||||
$tanaman->update([
|
||||
'jenis_hama' => $jenisHama,
|
||||
'jenis_penyakit' => $jenisPenyakit,
|
||||
'updated_by' => $praktikBudidaya->updated_by,
|
||||
]);
|
||||
});
|
||||
}
|
||||
// Salin jenis hama/penyakit ke semua lahan & tanaman petani: satu query per tabel
|
||||
// (sebelumnya satu query per baris; petani bisa punya ratusan titik tanaman).
|
||||
// Hanya baris yang isinya berbeda yang diubah, supaya updated_at baris lain tidak ikut berubah.
|
||||
self::sinkronHamaPenyakit(new Lahan, $praktikBudidaya, $jenisHama, $jenisPenyakit);
|
||||
self::sinkronHamaPenyakit(new Tanaman, $praktikBudidaya, $jenisHama, $jenisPenyakit);
|
||||
|
||||
if ($kebiasaan == 0) {
|
||||
$skor_konservasi_tanah = 1;
|
||||
@@ -146,6 +131,37 @@ class PraktikBudidaya extends Model
|
||||
});
|
||||
}
|
||||
|
||||
/** @var array<string, bool> hasil cek kolom per tabel (cukup sekali per proses) */
|
||||
private static array $punyaKolomHama = [];
|
||||
|
||||
private static function sinkronHamaPenyakit(Model $model, PraktikBudidaya $praktikBudidaya, array $jenisHama, array $jenisPenyakit): void
|
||||
{
|
||||
$tabel = $model->getTable();
|
||||
$ada = self::$punyaKolomHama[$tabel] ??= Schema::hasColumns($tabel, ['jenis_hama', 'jenis_penyakit']);
|
||||
if (! $ada) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Format JSON sama dengan cast 'array' di model Lahan/Tanaman.
|
||||
$hama = json_encode($jenisHama);
|
||||
$penyakit = json_encode($jenisPenyakit);
|
||||
|
||||
// Query builder: tidak memicu event per baris. Status petani sudah dikembalikan ke Draf
|
||||
// oleh event PraktikBudidaya sendiri (trait KembalikanStatusPetaniKeDraf).
|
||||
$model->newQuery()
|
||||
->where('petani_id', $praktikBudidaya->petani_id)
|
||||
// Kolom jsonb: dibandingkan sebagai jsonb (bukan teks) karena PostgreSQL menormalkan formatnya.
|
||||
->where(fn ($q) => $q
|
||||
->whereRaw('jenis_hama::jsonb IS DISTINCT FROM ?::jsonb', [$hama])
|
||||
->orWhereRaw('jenis_penyakit::jsonb IS DISTINCT FROM ?::jsonb', [$penyakit]))
|
||||
->update([
|
||||
'jenis_hama' => $hama,
|
||||
'jenis_penyakit' => $penyakit,
|
||||
'updated_by' => $praktikBudidaya->updated_by,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function petani(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Petani::class, 'petani_id');
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use App\Enums\SosialEkonomi\AlasanKreditDitolak;
|
||||
use App\Enums\SosialEkonomi\BisaBeliPupukBersubsidi;
|
||||
use App\Enums\SosialEkonomi\JenisAsetProduktif;
|
||||
@@ -51,7 +52,7 @@ use Illuminate\Support\Str;
|
||||
|
||||
class SosialEkonomi extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'sosial_ekonomi';
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@@ -11,7 +12,7 @@ use App\Models\Pertanian\Petani;
|
||||
|
||||
class SurveyPanen extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'survey_panen';
|
||||
|
||||
@@ -64,6 +65,9 @@ class SurveyPanen extends Model
|
||||
$skor->update([
|
||||
'skor_d2_k3_1_penentuan_pematangan' => $survey->dasar_penentuan_panen,
|
||||
'skor_d2_k3_5_sortasi_awal_pemisahan_kualitas' => $survey->praktik_sortasi,
|
||||
// Hambatan mutu = "Tingkat hasil panen ditolak pembeli" (TingkatPanenReject, 1–5).
|
||||
// Kolomnya bernama hasil_panen_reject, tetapi isinya tingkat reject.
|
||||
'skor_d6_k5_1_hambatan_mutu' => $survey->hasil_panen_reject,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -11,7 +12,7 @@ use App\Models\Pertanian\Petani;
|
||||
|
||||
class SurveyPelatihan extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'survey_pelatihan';
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class SurveyProduktivitas extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'survey_produktivitas';
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class SurveySertifikasi extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'survey_sertifikasi';
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Models\Profile;
|
||||
@@ -17,7 +18,7 @@ use App\Enums\KeparahanSerangan;
|
||||
|
||||
class Tanaman extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, KembalikanStatusPetaniKeDraf;
|
||||
|
||||
protected $table = 'map_tanaman';
|
||||
|
||||
@@ -80,4 +81,11 @@ class Tanaman extends Model
|
||||
{
|
||||
return $this->belongsTo(Lahan::class, 'lahan_id');
|
||||
}
|
||||
|
||||
// Untuk trait KembalikanStatusPetaniKeDraf: petani diambil dari lahannya.
|
||||
protected function petaniIdUntukStatus(): ?int
|
||||
{
|
||||
return $this->petani_id ?? self::ingatPerRequest('status_petani.lahan', $this->lahan_id,
|
||||
fn () => Lahan::withoutGlobalScopes()->whereKey($this->lahan_id)->value('petani_id'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user