feat: integrate activity logging into various models for enhanced tracking of changes

This commit is contained in:
Yoga Pangestu 2026-04-21 19:20:40 +07:00
parent 702b033a8b
commit 486d626ca2
11 changed files with 580 additions and 10 deletions

View File

@ -9,13 +9,16 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
#[Guarded(['id'])]
class Category extends Model
{
use HasFactory, HasSlug, SoftDeletes;
use HasFactory, HasSlug, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -47,4 +50,55 @@ public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'is_active'])
->logOnlyDirty()
->useLogName('Kategori');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'name' => 'Nama',
'is_active' => 'Status',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$displayValue = $value;
if ($key === 'is_active') {
$displayValue = $value ? 'Aktif' : 'Tidak Aktif';
}
$newAttrs[$label] = $displayValue;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -9,6 +9,9 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
@ -16,7 +19,7 @@
#[Appends(['proof_url'])]
class Expense extends Model implements HasMedia
{
use HasFactory, InteractsWithMedia, SoftDeletes;
use HasFactory, InteractsWithMedia, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -36,4 +39,49 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'amount'])
->logOnlyDirty()
->useLogName('Pengeluaran');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'name' => 'Nama Pengeluaran',
'amount' => 'Nominal',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -11,6 +11,9 @@
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
#[Appends([
@ -22,7 +25,7 @@
])]
class Payroll extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -79,4 +82,59 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['base_salary', 'bonus', 'deduction', 'total_salary', 'is_paid', 'period_month'])
->logOnlyDirty()
->useLogName('Penggajian');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'base_salary' => 'Gaji Pokok',
'bonus' => 'Bonus',
'deduction' => 'Potongan',
'total_salary' => 'Total Gaji',
'is_paid' => 'Status Pembayaran',
'period_month' => 'Periode',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$displayValue = $value;
if ($key === 'is_paid') {
$displayValue = $value ? 'Dibayar' : 'Belum Dibayar';
}
$newAttrs[$label] = $displayValue;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -10,12 +10,15 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
#[Appends(['amount_formatted'])]
class PayrollAdjustment extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -36,4 +39,56 @@ public function payroll(): BelongsTo
{
return $this->belongsTo(Payroll::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['type', 'description', 'amount'])
->logOnlyDirty()
->useLogName('Penyesuaian Gaji');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'type' => 'Jenis',
'description' => 'Keterangan',
'amount' => 'Nominal',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$displayValue = $value;
if ($key === 'type' && $value instanceof \BackedEnum) {
$displayValue = $value->value;
}
$newAttrs[$label] = $displayValue;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -12,6 +12,9 @@
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\Sluggable\HasSlug;
@ -21,7 +24,7 @@
#[Appends(['thumbnail_url', 'images_data'])]
class Product extends Model implements HasMedia
{
use HasFactory, HasSlug, InteractsWithMedia, SoftDeletes;
use HasFactory, HasSlug, InteractsWithMedia, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -84,4 +87,57 @@ public function prices(): HasMany
{
return $this->hasMany(ProductPrice::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'description', 'stock', 'is_active'])
->logOnlyDirty()
->useLogName('Produk');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'name' => 'Nama',
'description' => 'Deskripsi',
'stock' => 'Stok',
'is_active' => 'Status',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$displayValue = $value;
if ($key === 'is_active') {
$displayValue = $value ? 'Aktif' : 'Tidak Aktif';
}
$newAttrs[$label] = $displayValue;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -8,11 +8,16 @@
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
#[Appends(['price_formatted', 'price_type_label'])]
class ProductPrice extends Model
{
use LogsActivity;
protected function casts(): array
{
return [
@ -39,4 +44,55 @@ public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['price_type', 'price'])
->logOnlyDirty()
->useLogName('Harga Produk');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'price_type' => 'Jenis Harga',
'price' => 'Harga',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$displayValue = $value;
if ($key === 'price_type' && $value instanceof \BackedEnum) {
$displayValue = $value->value;
}
$newAttrs[$label] = $displayValue;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -9,12 +9,15 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
#[Appends(['total_formatted'])]
class Purchase extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -35,4 +38,50 @@ public function items(): HasMany
{
return $this->hasMany(PurchaseItem::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['purchase_date', 'total', 'note'])
->logOnlyDirty()
->useLogName('Pembelian');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'purchase_date' => 'Tanggal Beli',
'total' => 'Total',
'note' => 'Catatan',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -9,12 +9,15 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
#[Appends(['unit_price_formatted', 'total_price_formatted'])]
class PurchaseItem extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -53,4 +56,50 @@ public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['quantity', 'unit_price', 'total_price'])
->logOnlyDirty()
->useLogName('Item Pembelian');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'quantity' => 'Jumlah',
'unit_price' => 'Harga Satuan',
'total_price' => 'Total Harga',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -7,11 +7,14 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
class SalaryHistory extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -25,4 +28,49 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['old_salary', 'new_salary'])
->logOnlyDirty()
->useLogName('Riwayat Gaji');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'old_salary' => 'Gaji Lama',
'new_salary' => 'Gaji Baru',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -15,13 +15,16 @@
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded('id')]
#[Hidden(['password'])]
#[Appends(['name'])]
class User extends Authenticatable
{
use HasFactory, Notifiable, SoftDeletes, TwoFactorAuthenticatable;
use HasFactory, LogsActivity, Notifiable, SoftDeletes, TwoFactorAuthenticatable;
protected function casts(): array
{
@ -56,4 +59,48 @@ public function salaryHistories(): HasMany
{
return $this->hasMany(SalaryHistory::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['username'])
->logOnlyDirty()
->useLogName('Pegawai');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'username' => 'Username',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}

View File

@ -7,11 +7,14 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;
#[Guarded(['id'])]
class UserProfile extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes;
protected function casts(): array
{
@ -24,4 +27,51 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['full_name', 'phone', 'address', 'base_salary'])
->logOnlyDirty()
->useLogName('Profil Pegawai');
}
public function tapActivity(Activity $activity, string $eventName)
{
$activity->description = match ($eventName) {
'created' => 'TAMBAH',
'updated' => 'UBAH',
'deleted' => 'HAPUS',
default => $activity->description,
};
if (isset($activity->properties['attributes'])) {
$attributeMap = [
'full_name' => 'Nama Lengkap',
'phone' => 'No. Telepon',
'address' => 'Alamat',
'base_salary' => 'Gaji Pokok',
];
$properties = $activity->properties->toArray();
$localizeValues = function ($attrs) use ($attributeMap) {
$newAttrs = [];
foreach ($attrs as $key => $value) {
$label = $attributeMap[$key] ?? $key;
$newAttrs[$label] = $value;
}
return $newAttrs;
};
$properties['attributes'] = $localizeValues($properties['attributes']);
if (isset($properties['old'])) {
$properties['old'] = $localizeValues($properties['old']);
}
$activity->properties = collect($properties);
}
}
}