Update Log aktivitas

This commit is contained in:
2026-11-05 16:34:33 +07:00
parent a3ec431d49
commit 7a279ad5d2
84 changed files with 725 additions and 67 deletions
+2 -1
View File
@@ -341,6 +341,7 @@ class Lahan extends Model
- Pakai `$fillable`, bukan `$guarded = []`.
- Pilihan tetap (jawaban survei, status) disimpan sebagai **PHP Enum** di `app/Enums/` dan di-cast di model. Jangan menulis daftar pilihan langsung di Blade.
- **Jejak aktivitas:** setiap model memakai trait `App\Models\Concerns\CatatAktivitas` (spatie/laravel-activitylog). Tambah/ubah/hapus otomatis tercatat di `activity_log` dan tampil di menu Konfigurasi > Log Aktivitas. Kolom audit, `$hidden`, file/foto, dan polygon (`path`) tidak dicatat. Jika domain model baru belum ada, tambahkan labelnya di `LogAktivitasController::JENIS`. Aksi bisnis yang bukan sekadar simpan model (verifikasi, ganti status) dicatat manual dengan `activity('nama_log')->performedOn($model)->log('...')`. Perubahan lewat query massal (`->update()` pada query builder) **tidak** tercatat.
### 5.2 Migration
@@ -701,7 +702,7 @@ Status: `Belum` / `Proses` / `Selesai` / `Dikecualikan`
- [ ] Pola ditentukan (A/B/C) sesuai 3.3
- [ ] Migration: `id`, kolom audit, `timestamps`, `softDeletes`, `deleted_by`; tanpa unique index
- [ ] Model: `$table` eksplisit, `$fillable`, `SoftDeletes`, `deleted_by` terisi, casts/Enum
- [ ] Model: `$table` eksplisit, `$fillable`, `SoftDeletes`, `deleted_by` terisi, casts/Enum, trait `CatatAktivitas`
- [ ] Relasi anak ditambahkan ke cascade `deleting` di model induk
- [ ] Form Request `Store`/`Update` dengan pesan Bahasa Indonesia dan unique `withoutTrashed()`
- [ ] Controller di `Web/{Domain}/` dengan nama method resmi saja
@@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Web\Konfigurasi;
use App\Http\Controllers\Controller;
use App\Http\Requests\Konfigurasi\FilterLogAktivitasRequest;
use App\Models\Pertanian\Petani;
use App\Models\User;
use Illuminate\Support\Carbon;
use Spatie\Activitylog\Models\Activity;
class LogAktivitasController extends Controller
{
public const JENIS = [
'auth' => ['label' => 'Login', 'warna' => 'info'],
'petani' => ['label' => 'Profil Petani', 'warna' => 'primary'],
'verifikasi' => ['label' => 'Status Petani', 'warna' => 'success'],
'pertanian' => ['label' => 'Data Pertanian', 'warna' => 'primary'],
'map' => ['label' => 'Peta & Panen', 'warna' => 'primary'],
'user' => ['label' => 'Pengguna', 'warna' => 'warning'],
'profile' => ['label' => 'Profil Pengguna', 'warna' => 'warning'],
'konfigurasi' => ['label' => 'Konfigurasi', 'warna' => 'warning'],
'program' => ['label' => 'Program', 'warna' => 'danger'],
'core' => ['label' => 'Program (Inti)', 'warna' => 'danger'],
'bumdes' => ['label' => 'BUMDes', 'warna' => 'dark'],
'koperasi' => ['label' => 'Koperasi', 'warna' => 'dark'],
'ekosistem' => ['label' => 'Ekosistem', 'warna' => 'dark'],
'master' => ['label' => 'Master Data', 'warna' => 'secondary'],
'wilayah' => ['label' => 'Wilayah', 'warna' => 'secondary'],
'penduduk' => ['label' => 'Penduduk', 'warna' => 'secondary'],
'distribusi' => ['label' => 'Distribusi', 'warna' => 'secondary'],
'facilitator' => ['label' => 'Fasilitator', 'warna' => 'secondary'],
];
public const PER_PAGE = [25, 50, 100];
public function index(FilterLogAktivitasRequest $request)
{
$filter = $request->validated();
// Ambil log sesuai filter
$aktivitas = Activity::query()
->with(['causer', 'subject'])
->when($filter['jenis'] ?? null, fn ($q, $jenis) => $q->where('log_name', $jenis))
->when($filter['dari'] ?? null, fn ($q, $tgl) => $q->where('created_at', '>=', $tgl))
->when($filter['sampai'] ?? null, fn ($q, $tgl) => $q->where('created_at', '<', Carbon::parse($tgl)->addDay()))
->when($filter['search'] ?? null, fn ($q, $cari) => $this->cari($q, '%' . mb_strtolower($cari) . '%'))
->latest('id')
->paginate((int) ($filter['per_page'] ?? self::PER_PAGE[0]))
->withQueryString();
// Nama petani untuk log tab petani (satu query)
$namaPetani = Petani::withoutGlobalScopes()->withTrashed()
->whereIn('id', $aktivitas->getCollection()->pluck('properties.petani_id')->filter()->unique())
->pluck('nama', 'id');
return view('konfigurasi.log-aktivitas.index', [
'aktivitas' => $aktivitas,
'jenis' => self::JENIS,
'perPage' => self::PER_PAGE,
'namaPetani' => $namaPetani,
]);
}
// Cari di aktivitas, nama pengguna, dan nama petani
private function cari($query, string $cari): void
{
$query->where(fn ($q) => $q
->whereRaw('lower(description) like ?', [$cari])
->orWhereHasMorph('causer', [User::class], fn ($q) => $q->whereRaw('lower(name) like ?', [$cari]))
->orWhereRaw(
"coalesce((properties->>'petani_id')::bigint, case when subject_type = ? then subject_id end) in (select id from petani where lower(nama) like ?)",
[Petani::class, $cari]
));
}
}
@@ -47,10 +47,15 @@ class PetaniStatusController extends Controller
return back()->with('status_petani_error', 'Data petani masih berstatus draf.');
}
$dari = $petani->status;
$petani->status = $tujuan;
$petani->updated_by = $request->user()->id;
$petani->save();
$petani->catatPerubahanStatus($dari, $tujuan === StatusDataPetani::LENGKAP
? 'Ditandai lengkap oleh enumerator'
: 'Tanda lengkap dibatalkan oleh enumerator');
return back()->with('status_petani_success', $tujuan === StatusDataPetani::LENGKAP
? 'Data petani berhasil ditandai lengkap.'
: 'Tanda lengkap berhasil dibatalkan. Status kembali ke draf.');
@@ -96,6 +96,8 @@ class VerifikasiPetaniController extends Controller
$petani->updated_by = auth()->id();
$petani->save();
$petani->catatPerubahanStatus(StatusDataPetani::LENGKAP, 'Diverifikasi');
return $kembali->with('verifikasi_success', "Data petani {$petani->nama} berhasil diverifikasi.");
}
@@ -120,11 +122,14 @@ class VerifikasiPetaniController extends Controller
return $kembali->with('verifikasi_error', "Data petani {$petani->nama} sudah berstatus Draf.");
}
$dari = $petani->status;
$petani->status = StatusDataPetani::DRAFT;
$petani->catatan = trim($data['catatan']);
$petani->updated_by = auth()->id();
$petani->save();
$petani->catatPerubahanStatus($dari, 'Dikembalikan ke draf oleh verifikator', ['catatan' => $petani->catatan]);
return $kembali->with('verifikasi_success', "Data petani {$petani->nama} dikembalikan ke Draf dengan catatan untuk enumerator.");
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Http\Requests\Konfigurasi;
use App\Http\Controllers\Web\Konfigurasi\LogAktivitasController;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rule;
class FilterLogAktivitasRequest extends FormRequest
{
public function authorize(): bool
{
return Gate::any(['super_admin', 'admin']);
}
public function rules(): array
{
return [
'jenis' => ['nullable', Rule::in(array_keys(LogAktivitasController::JENIS))],
'search' => ['nullable', 'string', 'max:100'],
'dari' => ['nullable', 'date'],
'sampai' => ['nullable', 'date', 'after_or_equal:dari'],
'per_page' => ['nullable', 'integer', Rule::in(LogAktivitasController::PER_PAGE)],
];
}
public function messages(): array
{
return [
'sampai.after_or_equal' => 'Tanggal akhir tidak boleh sebelum tanggal awal.',
'per_page.in' => 'Jumlah data per halaman tidak valid.',
];
}
public function attributes(): array
{
return [
'jenis' => 'jenis aktivitas',
'search' => 'kata kunci',
'dari' => 'tanggal awal',
'sampai' => 'tanggal akhir',
];
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Contracts\Auth\Authenticatable;
class CatatAktivitasAuth
{
// Log login berhasil
public function handleLogin(Login $event): void
{
$this->catat('login', $event->remember ? 'Login (ingat saya)' : 'Login', $event->user, $event->guard);
}
// Log logout
public function handleLogout(Logout $event): void
{
if ($event->user) {
$this->catat('logout', 'Logout', $event->user, $event->guard);
}
}
// Log login gagal (tanpa password)
public function handleFailed(Failed $event): void
{
$identitas = collect($event->credentials)->except('password')->first();
$this->catat('login_gagal', 'Login gagal', $event->user, $event->guard, ['identitas' => $identitas]);
}
private function catat(string $event, string $keterangan, ?Authenticatable $user, ?string $guard, array $tambahan = []): void
{
activity('auth')
->causedBy($user)
->event($event)
->withProperties([
'ip' => request()->ip(),
'user_agent' => str(request()->userAgent())->limit(250)->toString(),
'guard' => $guard,
...$tambahan,
])
->log($keterangan);
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Bumdes;
use App\Models\Concerns\CatatAktivitas;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class KelembagaanAktorBumdes extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'bumdes_kelembagaan_aktor';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Bumdes;
use App\Models\Concerns\CatatAktivitas;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Pendidikan;
use App\Models\User;
@@ -14,7 +15,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class PengurusBumdes extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'bumdes_pengurus';
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace App\Models\Concerns;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Spatie\Activitylog\Models\Concerns\LogsActivity;
use Spatie\Activitylog\Support\LogOptions;
trait CatatAktivitas
{
use LogsActivity;
protected static array $kolomTidakDicatat = [
'created_by', 'updated_by', 'deleted_by', 'created_at', 'updated_at', 'deleted_at',
'password', 'remember_token', 'sync_status',
'foto', 'foto_url', 'path', 'path_kk', 'path_ktp', 'file_kk', 'file_ktp',
];
protected static array $kataEvent = [
'created' => 'ditambahkan',
'updated' => 'diubah',
'deleted' => 'dihapus',
'restored' => 'dipulihkan',
];
// Aturan log: kolom fillable yang berubah saja
public function getActivitylogOptions(): LogOptions
{
$label = property_exists($this, 'labelAktivitas') ? $this->labelAktivitas : Str::headline(class_basename($this));
$logName = property_exists($this, 'logAktivitas') ? $this->logAktivitas : Str::snake(explode('\\', static::class)[2]);
return LogOptions::defaults()
->useLogName($logName)
->logFillable()
->logExcept([...self::$kolomTidakDicatat, ...$this->getHidden()])
->dontLogIfAttributesChangedOnly(self::$kolomTidakDicatat)
->logOnlyDirty()
->dontLogEmptyChanges()
->setDescriptionForEvent(fn (string $event) => $label . ' ' . (self::$kataEvent[$event] ?? $event));
}
// Tandai petani terkait
public function beforeActivityLogged(Model $activity, string $event): void
{
if ($petaniId = $this->getAttribute('petani_id')) {
$activity->properties = $activity->properties->put('petani_id', (int) $petaniId);
}
}
}
@@ -54,7 +54,15 @@ trait KembalikanStatusPetaniKeDraf
->where('status', StatusDataPetani::LENGKAP->value)
->update(['status' => StatusDataPetani::DRAFT->value]);
if ($diubah && request()->hasSession()) {
if (! $diubah) {
return true;
}
// Log status (tanpa query ulang petani)
(new Petani)->forceFill(['id' => $petaniId, 'status' => StatusDataPetani::DRAFT])
->catatPerubahanStatus(StatusDataPetani::LENGKAP, 'Otomatis kembali ke draf karena data diubah', ['sumber' => class_basename($this)]);
if (request()->hasSession()) {
request()->session()->flash('status_petani_info', 'Data petani diubah, status kembali ke Draf. Tandai lengkap lagi setelah selesai.');
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Core;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -10,7 +11,7 @@ use App\Models\Pertanian\Komoditas;
class KomoditasProgram extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'core_program_komoditas';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Core;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -13,7 +14,7 @@ use App\Models\Wilayah\DesaKelurahan;
class LokasiProgram extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'core_program_lokasi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Core;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -11,7 +12,7 @@ use App\Models\Core\LokasiProgram;
class Program extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'core_program';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Distribusi;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Distribution extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'distribusi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -15,7 +16,7 @@ use App\Enums\LayoutForm;
class FormBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_form';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -10,7 +11,7 @@ use App\Models\Ekosistem\TabelBasisData;
class GroupBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_group';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -11,7 +12,7 @@ use App\Models\Ekosistem\TabelBasisData;
class KolomBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_kolom';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -11,7 +12,7 @@ use Enums\StatusLahan;
class LahanCPCL extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_lahan_cpcl';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -17,7 +18,7 @@ use App\Enums\HubunganDalamKeluarga;
class PetaniCPM extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_petani_cpm';
protected $appends = ['umur'];
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -13,7 +14,7 @@ use App\Models\Core\Program;
class RingkasanBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_ringkasan';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -18,7 +19,7 @@ use App\Models\Ekosistem\FormBasisData;
class TabelBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_tabel';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Ekosistem;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -11,7 +12,7 @@ use App\Models\Ekosistem\KolomBasisData;
class ValueBasisData extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'ekosistem_basis_data_value';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Facilitator;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Facilitator extends Model
{
use HasFactory;
use HasFactory, CatatAktivitas;
// Menentukan nama tabel jika tidak jamak (optional)
protected $table = 'facilitator';
@@ -2,6 +2,7 @@
namespace App\Models\Konfigurasi;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\HasDeletedBy;
use App\Models\Pertanian\Komoditas;
use App\Models\User;
@@ -11,7 +12,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class KoordinatorKomoditas extends Model
{
use SoftDeletes, HasDeletedBy;
use SoftDeletes, HasDeletedBy, CatatAktivitas;
protected $table = 'koordinator_komoditas';
+3
View File
@@ -2,10 +2,13 @@
namespace App\Models\Koperasi;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
class PengurusKoperasi extends Model
{
use CatatAktivitas;
protected $table = 'pengurus_koperasi';
protected $fillable = [
+2 -1
View File
@@ -2,12 +2,13 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class InsLahan extends Model
{
use HasFactory;
use HasFactory, CatatAktivitas;
protected $table = 'lahan_inspeksi';
+2 -1
View File
@@ -2,12 +2,13 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Inspeksi extends Model{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'tanaman_inspeksi';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Lahan extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'map_lahan';
+2 -1
View File
@@ -1,13 +1,14 @@
<?php
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // Wajib diimport
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Offtaker extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'offtakers';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -11,7 +12,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class Panen extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
// Nama tabel sesuai DDL sebelumnya
protected $table = 'map_panen';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PanenKomoditas extends Pivot
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'panen_komoditas';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PanenTanaman extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'panen_tanaman';
protected $fillable = [
"panen_id",
+2 -1
View File
@@ -2,12 +2,13 @@
namespace App\Models\Map;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tanaman extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'map_tanaman';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Master;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -9,7 +10,7 @@ use App\Models\Pertanian\Komoditas;
class JenisKomoditas extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'jenis_komoditas';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Master;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class JenisTanaman extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'master_jenis_tanaman';
+3
View File
@@ -2,6 +2,7 @@
namespace App\Models\Master;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -10,6 +11,8 @@ use App\Models\Master\JenisKomoditas;
class Varietas extends Model
{
use CatatAktivitas;
protected $table = 'master_varietas';
protected $fillable = [
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Penduduk;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\DesaKelurahan;
@@ -9,7 +10,7 @@ use App\Models\Pertanian\Adat;
class Keluarga extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'keluarga';
+3
View File
@@ -2,9 +2,12 @@
namespace App\Models\Penduduk;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
use CatatAktivitas;
//
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\DesaKelurahan;
@@ -9,7 +10,7 @@ use App\Models\Pertanian\Lahan;
class Adat extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'adat';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -16,7 +17,7 @@ use App\Enums\AksesPasar\SkorKesadaranPremium;
class AksesPasar extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'akses_pasar';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
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 AsetKelompokTani extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'survey_aset_kelompok_tani';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
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 BantuanKelompokTani extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'survey_bantuan_kelompok_tani';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
@@ -9,7 +10,7 @@ use App\Models\Pertanian\Petani;
class HargaJualPanen extends Model
{
use KembalikanStatusPetaniKeDraf;
use KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'harga_jual_panen';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class JenisKomoditas extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
/**
* Nama tabel yang terkait dengan model ini.
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -12,7 +13,7 @@ use App\Models\Wilayah\DesaKelurahan;
class KelompokTani extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
public const STATUS_LEGALITAS_DENGAN_SK = [
'Sudah ada SK dari desa/kecamatan',
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;
@@ -12,7 +13,7 @@ use App\Models\Pertanian\Petani;
class Komoditas extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'master_komoditas';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -23,7 +24,7 @@ use App\Models\Pertanian\Petani;
class Lahan extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'map_lahan';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PendapatanKomoditas extends Model
{
use KembalikanStatusPetaniKeDraf;
use KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'pendapatan_komoditas';
@@ -2,13 +2,14 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PendapatanLuarPertanian extends Model
{
use KembalikanStatusPetaniKeDraf;
use KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'pendapatan_luar_pertanian';
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
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 PengurusKelompokTani extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'survey_pengurus_kelompok_tani';
+15 -1
View File
@@ -28,10 +28,14 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use App\Models\Concerns\CatatAktivitas;
class Petani extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected string $logAktivitas = 'petani';
protected string $labelAktivitas = 'Data petani';
protected $table = 'petani';
@@ -81,6 +85,16 @@ class Petani extends Model
'status' => 'draft',
];
// Log perpindahan status petani
public function catatPerubahanStatus(StatusDataPetani $dari, string $keterangan, array $tambahan = []): void
{
activity('verifikasi')
->performedOn($this)
->event('status')
->withProperties(array_filter(['dari' => $dari->value, 'ke' => $this->status?->value, ...$tambahan]))
->log($keterangan);
}
public function getUmurAttribute(): ?int
{
if (! $this->tanggal_lahir) {
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -19,7 +20,7 @@ use App\Models\Pertanian\Lahan;
class PraktikBudidaya extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'praktik_budidaya';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Profile;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Produksi extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'produksi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use App\Enums\SosialEkonomi\AlasanKreditDitolak;
use App\Enums\SosialEkonomi\BisaBeliPupukBersubsidi;
@@ -52,7 +53,7 @@ use Illuminate\Support\Str;
class SosialEkonomi extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'sosial_ekonomi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -12,7 +13,7 @@ use App\Models\Pertanian\Petani;
class SurveyPanen extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'survey_panen';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -12,7 +13,7 @@ use App\Models\Pertanian\Petani;
class SurveyPelatihan extends Model
{
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf;
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'survey_pelatihan';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -10,7 +11,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class SurveyProduktivitas extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'survey_produktivitas';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -10,7 +11,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class SurveySertifikasi extends Model
{
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf;
use HasFactory, SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'survey_sertifikasi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Pertanian;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Concerns\KembalikanStatusPetaniKeDraf;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -18,7 +19,7 @@ use App\Enums\KeparahanSerangan;
class Tanaman extends Model
{
use SoftDeletes, KembalikanStatusPetaniKeDraf;
use SoftDeletes, KembalikanStatusPetaniKeDraf, CatatAktivitas;
protected $table = 'map_tanaman';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -11,7 +12,7 @@ use App\Models\Pertanian\Lahan;
class Profile extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $fillable = [
'user_id',
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -12,7 +13,7 @@ use App\Models\Program\Target;
class Aktivitas extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_aktivitas';
+3
View File
@@ -2,11 +2,14 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
class DetailKelompok extends Model
{
use CatatAktivitas;
protected $table = 'detail_kelompok';
protected $fillable = [
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -12,7 +13,7 @@ use App\Models\Program\Transformasi;
class Framework extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_framework';
+2 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Program\DetailKelompok;
class KelompokBelajarTani extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'kelompok_belajar_tani';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -11,7 +12,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PesertaWorkshop extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'peserta_workshop';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -11,7 +12,7 @@ use App\Models\Program\Target;
class Realisasi extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_realisasi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -12,7 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class SesiWorkshop extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'sesi_workshop';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -12,7 +13,7 @@ use App\Models\Program\Aktivitas;
class Target extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_target';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -12,7 +13,7 @@ use App\Models\Program\Aktivitas;
class Transformasi extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_transformasi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -10,7 +11,7 @@ use App\Models\Program\Realisasi;
class Verifikasi extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'program_verifikasi';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Program;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -14,7 +15,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class Workshop extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, CatatAktivitas;
protected $table = 'workshop';
+11 -1
View File
@@ -11,13 +11,16 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Laravel\Sanctum\HasApiTokens;
use App\Models\Concerns\CatatAktivitas;
use App\Models\Konfigurasi\KoordinatorKomoditas;
use App\Models\Pertanian\Petani;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens, SoftDeletes;
use HasFactory, Notifiable, HasApiTokens, SoftDeletes, CatatAktivitas;
protected string $labelAktivitas = 'Pengguna';
protected $fillable = [
'name',
@@ -63,6 +66,13 @@ class User extends Authenticatable
$user->koordinatorKomoditas()->get()->each->delete();
});
// Log ganti password (tanpa isi)
static::updated(function (User $user) {
if ($user->wasChanged('password')) {
activity('user')->performedOn($user)->event('password')->log('Password diubah');
}
});
}
public function koordinatorKomoditas(): HasMany
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Wilayah;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\Kecamatan;
@@ -12,7 +13,7 @@ use Illuminate\Database\Eloquent\Builder;
class DesaKelurahan extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'master_desa_kelurahan';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Wilayah;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\Provinsi;
@@ -12,7 +13,7 @@ use Illuminate\Database\Eloquent\Builder;
class KabupatenKota extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'master_kabupaten_kota';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Wilayah;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\KabupatenKota;
@@ -12,7 +13,7 @@ use Illuminate\Database\Eloquent\Builder;
class Kecamatan extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'master_kecamatan';
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Models\Wilayah;
use App\Models\Concerns\CatatAktivitas;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Wilayah\KabupatenKota;
@@ -11,7 +12,7 @@ use Illuminate\Database\Eloquent\Builder;
class Provinsi extends Model
{
use SoftDeletes;
use SoftDeletes, CatatAktivitas;
protected $table = 'master_provinsi';
+6
View File
@@ -15,6 +15,7 @@ use Dedoc\Scramble\Support\Generator\OpenApi;
use Dedoc\Scramble\Support\Generator\SecurityScheme;
use App\Models\Ekosistem\TabelBasisData;
use Spatie\Activitylog\Support\ActivityLogStatus;
class AppServiceProvider extends ServiceProvider
{
@@ -31,6 +32,11 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
// Matikan log aktivitas saat seeding
if ($this->app->runningConsoleCommand('db:seed', 'migrate:fresh', 'migrate:refresh', 'migrate:reset')) {
app(ActivityLogStatus::class)->disable();
}
Scramble::configure()
->withDocumentTransformers(function (OpenApi $openApi) {
$openApi->secure(
@@ -0,0 +1,47 @@
<?php
namespace App\Services\Konfigurasi;
use App\Enums\StatusDataPetani;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
class FormatLogAktivitas
{
private const LABEL_KOLOM = [
'nomor_telepon' => 'No. Telepon',
'kk' => 'No. KK',
'ktp' => 'No. KTP',
'uid' => 'UID',
];
// Nama kolom → label (desa_kelurahan_id → Desa Kelurahan (ID))
public static function kolom(string $kolom): string
{
return self::LABEL_KOLOM[$kolom]
?? (str_ends_with($kolom, '_id') ? Str::headline(substr($kolom, 0, -3)) . ' (ID)' : Str::headline($kolom));
}
// Nilai kolom → teks tampilan
public static function nilai(string $kolom, mixed $nilai): string
{
return match (true) {
$nilai === null || $nilai === '' => '-',
$kolom === 'jenis_kelamin' => $nilai ? 'Laki-laki' : 'Perempuan',
is_bool($nilai) => $nilai ? 'Ya' : 'Tidak',
self::kolomTanggal($kolom, $nilai) => Carbon::parse($nilai)->translatedFormat('d M Y'),
default => Str::limit(is_scalar($nilai) ? (string) $nilai : json_encode($nilai, JSON_UNESCAPED_UNICODE), 120),
};
}
public static function status(?string $nilai): string
{
return StatusDataPetani::tryFrom((string) $nilai)?->label() ?? '-';
}
private static function kolomTanggal(string $kolom, mixed $nilai): bool
{
return (str_starts_with($kolom, 'tanggal') || str_starts_with($kolom, 'tgl_'))
&& is_string($nilai) && strtotime($nilai) !== false;
}
}
+73
View File
@@ -0,0 +1,73 @@
<?php
use Spatie\Activitylog\Actions\CleanActivityLogAction;
use Spatie\Activitylog\Actions\LogActivityAction;
use Spatie\Activitylog\Models\Activity;
return [
/*
* If set to false, no activities will be saved to the database.
*/
'enabled' => env('ACTIVITYLOG_ENABLED', true),
/*
* When the clean command is executed, all recording activities older than
* the number of days specified here will be deleted.
*/
'clean_after_days' => 365,
/*
* If no log name is passed to the activity() helper
* we use this default log name.
*/
'default_log_name' => 'default',
/*
* You can specify an auth driver here that gets user models.
* If this is null we'll use the current Laravel auth driver.
*/
'default_auth_driver' => null,
/*
* If set to true, the subject relationship on activities
* will include soft deleted models.
*/
'include_soft_deleted_subjects' => true,
/*
* This model will be used to log activity.
* It should implement the Spatie\Activitylog\Contracts\Activity interface
* and extend Illuminate\Database\Eloquent\Model.
*/
'activity_model' => Activity::class,
/*
* These attributes will be excluded from logging for all models.
* Model-specific exclusions via logExcept() are merged with these.
*/
'default_except_attributes' => [],
/*
* When enabled, activities are buffered in memory and inserted in a
* single bulk query after the response has been sent to the client.
* This can significantly reduce the number of database queries when
* many activities are logged during a single request.
*
* Only enable this if your application logs a high volume of activities
* per request. Buffered activities will not have an ID until the
* buffer is flushed.
*/
'buffer' => [
'enabled' => env('ACTIVITYLOG_BUFFER_ENABLED', true),
],
/*
* These action classes can be overridden to customize how activities
* are logged and cleaned. Your custom classes must extend the originals.
*/
'actions' => [
'log_activity' => LogActivityAction::class,
'clean_log' => CleanActivityLogAction::class,
],
];
@@ -0,0 +1,25 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('activity_log', function (Blueprint $table) {
$table->id();
$table->string('log_name')->nullable()->index();
$table->text('description');
$table->nullableMorphs('subject', 'subject');
$table->string('event')->nullable();
$table->nullableMorphs('causer', 'causer');
$table->json('attribute_changes')->nullable();
$table->json('properties')->nullable();
$table->timestamps();
$table->index('created_at');
});
}
};
@@ -0,0 +1,161 @@
@extends('layout.main')
@use('App\Services\Konfigurasi\FormatLogAktivitas', 'Format')
@use('App\Models\Pertanian\Petani')
@use('Illuminate\Support\Str')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-1">Log Aktivitas</h5>
<small class="text-body-secondary">Jejak perubahan data, status petani, dan login pengguna.</small>
</div>
{{-- Filter --}}
<div class="card-body pt-4">
<form method="GET" action="{{ route('log-aktivitas.index') }}" class="row g-3 align-items-end">
<div class="col-md-2">
<label class="form-label" for="jenis">Jenis</label>
<select id="jenis" name="jenis" class="form-select form-select-sm">
<option value="">Semua</option>
@foreach ($jenis as $kunci => $j)
<option value="{{ $kunci }}" @selected(request('jenis') === $kunci)>{{ $j['label'] }}</option>
@endforeach
</select>
</div>
<div class="col-md-2">
<label class="form-label" for="dari">Dari Tanggal</label>
<input type="date" id="dari" name="dari" value="{{ request('dari') }}"
class="form-control form-control-sm @error('dari') is-invalid @enderror">
@error('dari')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-2">
<label class="form-label" for="sampai">Sampai Tanggal</label>
<input type="date" id="sampai" name="sampai" value="{{ request('sampai') }}"
class="form-control form-control-sm @error('sampai') is-invalid @enderror">
@error('sampai')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-1">
<label class="form-label" for="per_page">Tampil</label>
<select id="per_page" name="per_page" class="form-select form-select-sm">
@foreach ($perPage as $n)
<option value="{{ $n }}" @selected($aktivitas->perPage() == $n)>{{ $n }}</option>
@endforeach
</select>
</div>
<div class="col-md-5">
<label class="form-label" for="search">Cari</label>
<div class="input-group input-group-sm">
<input type="text" id="search" name="search" class="form-control" value="{{ request('search') }}"
placeholder="Aktivitas, nama pengguna, atau nama petani...">
<button type="submit" class="btn btn-primary"><i class="icon-base ti tabler-search"></i></button>
@if (request()->hasAny(['jenis', 'search', 'dari', 'sampai']))
<a href="{{ route('log-aktivitas.index') }}" class="btn btn-label-secondary">Reset</a>
@endif
</div>
</div>
</form>
</div>
{{-- Tabel log --}}
<div class="table-responsive">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th class="text-nowrap">Waktu</th>
<th>Pengguna</th>
<th>Jenis</th>
<th>Aktivitas</th>
<th>Rincian</th>
</tr>
</thead>
<tbody>
@forelse ($aktivitas as $item)
@php
$j = $jenis[$item->log_name] ?? ['label' => $item->log_name ?? '-', 'warna' => 'secondary'];
$prop = $item->properties ?? collect();
$baru = $item->attribute_changes['attributes'] ?? [];
$lama = $item->attribute_changes['old'] ?? null;
$petaniId = $item->subject_type === Petani::class ? $item->subject_id : ($prop['petani_id'] ?? null);
$namaData = $item->subject?->nama ?? $item->subject?->name;
@endphp
<tr>
<td class="text-nowrap">
<span class="d-block">{{ $item->created_at->translatedFormat('d M Y') }}</span>
<small class="text-body-secondary">{{ $item->created_at->format('H:i:s') }}</small>
</td>
<td>
@if ($item->causer)
<span class="text-heading fw-medium d-block">{{ $item->causer->name }}</span>
<small class="text-body-secondary">{{ $item->causer->role?->label() }}</small>
@else
<span class="text-body-secondary">Sistem / tamu</span>
@endif
</td>
<td><span class="badge bg-label-{{ $j['warna'] }}">{{ $j['label'] }}</span></td>
<td>
<span class="d-block">{{ $item->description }}</span>
@if ($item->subject_type && $item->subject_type !== Petani::class)
<small class="text-body-secondary d-block">#{{ $item->subject_id }}{{ $namaData ? ' · ' . Str::limit($namaData, 40) : '' }}</small>
@endif
@if ($petaniId)
<small class="text-body-secondary d-block">
<i class="icon-base ti tabler-user icon-xs"></i>
{{ $namaPetani[$petaniId] ?? $namaData ?? 'Petani #' . $petaniId }}
</small>
@endif
</td>
<td class="small">
@if ($item->log_name === 'verifikasi')
<span class="badge bg-label-secondary">{{ Format::status($prop['dari'] ?? null) }}</span>
<i class="icon-base ti tabler-arrow-right icon-xs mx-1"></i>
<span class="badge bg-label-primary">{{ Format::status($prop['ke'] ?? null) }}</span>
@if (! empty($prop['catatan']))
<div class="mt-1 text-wrap" style="max-width: 360px;">Catatan: {{ $prop['catatan'] }}</div>
@endif
@elseif ($item->log_name === 'auth')
<span class="d-block">IP: {{ $prop['ip'] ?? '-' }}</span>
@if (! empty($prop['identitas']))
<span class="d-block">Login: {{ $prop['identitas'] }}</span>
@endif
@elseif ($baru)
@php
$isian = collect($baru)->when(! $lama, fn ($c) => $c->reject(fn ($v) => $v === null || $v === ''));
$batas = $lama ? $isian->count() : 5;
@endphp
<ul class="list-unstyled mb-0">
@foreach ($isian->take($batas) as $kolom => $nilai)
<li class="text-wrap" style="max-width: 420px;">
<span class="fw-medium">{{ Format::kolom($kolom) }}:</span>
@if ($lama)
<span class="text-body-secondary text-decoration-line-through">{{ Format::nilai($kolom, $lama[$kolom] ?? null) }}</span>
<i class="icon-base ti tabler-arrow-right icon-xs mx-1"></i>
@endif
{{ Format::nilai($kolom, $nilai) }}
</li>
@endforeach
@if ($isian->count() > $batas)
<li class="text-body-secondary">+{{ $isian->count() - $batas }} isian lainnya</li>
@endif
</ul>
@else
<span class="text-body-secondary">-</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center py-4">Belum ada aktivitas yang tercatat.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="d-flex justify-content-center justify-content-md-end border-top p-4">
{{ $aktivitas->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
+6 -1
View File
@@ -260,7 +260,7 @@
@endif
@if($isAdmin)
<li class="menu-item {{ request()->routeIs(['users.*', 'program.*', 'framework.*', 'group.*']) || (request()->routeIs('tabel.*') && !request()->routeIs('tabel.data.*')) ? 'active open' : '' }}">
<li class="menu-item {{ request()->routeIs(['users.*', 'log-aktivitas.*', 'program.*', 'framework.*', 'group.*']) || (request()->routeIs('tabel.*') && !request()->routeIs('tabel.data.*')) ? 'active open' : '' }}">
<a href="javascript:void(0);" class="menu-link menu-toggle">
<span class="menu-icon sidebar-icon" aria-hidden="true"><i class="icon-base ti tabler-settings"></i></span>
<div data-i18n="Konfigurasi">Konfigurasi</div>
@@ -271,6 +271,11 @@
<span class="menu-icon sidebar-icon" aria-hidden="true"><i class="icon-base ti tabler-user-shield"></i></span><div data-i18n="Daftar Pengguna">Daftar Pengguna</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs('log-aktivitas.*') ? 'active' : '' }}">
<a href="{{ route('log-aktivitas.index') }}" class="menu-link">
<span class="menu-icon sidebar-icon" aria-hidden="true"><i class="icon-base ti tabler-history"></i></span><div data-i18n="Log Aktivitas">Log Aktivitas</div>
</a>
</li>
@if($isAdmin && $appName === 'AgroPro')
<li class="menu-item {{ request()->routeIs(['program.*', 'framework.*']) ? 'active open' : '' }}">
+3
View File
@@ -6,3 +6,6 @@ use Illuminate\Support\Facades\Artisan;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');
// Bersihkan log aktivitas lama
Illuminate\Support\Facades\Schedule::command('activitylog:clean')->daily();
+3
View File
@@ -89,6 +89,9 @@ Route::middleware('auth')
Route::put('/users/{user}/verify', [App\Http\Controllers\Web\Konfigurasi\UserController::class, 'verify'])->name('users.verify');
Route::singleton('users.komoditas', App\Http\Controllers\Web\Konfigurasi\KoordinatorKomoditasController::class)->only(['update']);
// Log Aktivitas
Route::resource('log-aktivitas', App\Http\Controllers\Web\Konfigurasi\LogAktivitasController::class)->only(['index']);
// Provinsi
Route::get('/provinsi/list', [App\Http\Controllers\Web\Master\ProvinsiController::class, 'list'])->name('provinsi.list');
Route::get('/provinsi', [App\Http\Controllers\Web\Master\ProvinsiController::class, 'index'])->name('provinsi.index');