227 lines
7.5 KiB
PHP
227 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Concerns;
|
|
|
|
use App\Models\FormHistory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
trait LogsFormHistory
|
|
{
|
|
private function logCreated(Model $model, string $module, array $newValues): void
|
|
{
|
|
$changes = $this->buildCreatedChanges($newValues);
|
|
|
|
FormHistory::create([
|
|
'causer_id' => Auth::id(),
|
|
'module' => $module,
|
|
'event' => 'created',
|
|
'description' => "{$module} ditambahkan",
|
|
'attribute_changes' => $changes ?: null,
|
|
]);
|
|
}
|
|
|
|
private function logUpdated(Model $model, string $module, array $oldValues, array $newValues, array $alwaysInclude = []): void
|
|
{
|
|
$changes = $this->buildUpdatedChanges($oldValues, $newValues, $alwaysInclude);
|
|
|
|
FormHistory::create([
|
|
'causer_id' => Auth::id(),
|
|
'module' => $module,
|
|
'event' => 'updated',
|
|
'description' => "{$module} diperbarui",
|
|
'attribute_changes' => $changes ?: null,
|
|
]);
|
|
}
|
|
|
|
private function logDeleted(Model $model, string $module, array $oldValues): void
|
|
{
|
|
$changes = $this->buildDeletedChanges($oldValues);
|
|
|
|
FormHistory::create([
|
|
'causer_id' => Auth::id(),
|
|
'module' => $module,
|
|
'event' => 'deleted',
|
|
'description' => "{$module} dihapus",
|
|
'attribute_changes' => $changes ?: null,
|
|
]);
|
|
}
|
|
|
|
private function resolveItemName(array $item): string
|
|
{
|
|
$nameKeys = ['Nama Varian', 'Nama', 'name', 'variant', 'Variant', 'variant_name'];
|
|
|
|
foreach ($nameKeys as $nameKey) {
|
|
if (! empty($item[$nameKey])) {
|
|
return (string) $item[$nameKey];
|
|
}
|
|
}
|
|
|
|
return '?';
|
|
}
|
|
|
|
private function buildCreatedChanges(array $newValues): array
|
|
{
|
|
$changes = [];
|
|
|
|
foreach ($newValues as $key => $value) {
|
|
if (is_array($value)) {
|
|
foreach ($value as $item) {
|
|
if (is_array($item)) {
|
|
$itemName = $this->resolveItemName($item);
|
|
foreach ($item as $subKey => $subValue) {
|
|
$changes["{$key}: {$itemName} — {$subKey}"] = ['new' => $subValue];
|
|
}
|
|
} else {
|
|
$changes["{$key}: {$item}"] = ['new' => null];
|
|
}
|
|
}
|
|
} else {
|
|
$changes[$key] = ['new' => $value];
|
|
}
|
|
}
|
|
|
|
return $changes;
|
|
}
|
|
|
|
private function buildUpdatedChanges(array $oldValues, array $newValues, array $alwaysInclude = []): array
|
|
{
|
|
$changes = [];
|
|
$allKeys = array_unique(array_merge(array_keys($oldValues), array_keys($newValues)));
|
|
|
|
foreach ($allKeys as $key) {
|
|
$old = $oldValues[$key] ?? null;
|
|
$new = $newValues[$key] ?? null;
|
|
|
|
if (is_array($old) && is_array($new)) {
|
|
$nestedChanges = $this->diffArray($old, $new, $key);
|
|
$changes = array_merge($changes, $nestedChanges);
|
|
} elseif ($old !== $new) {
|
|
$changes[$key] = array_filter([
|
|
'old' => $old ?? null,
|
|
'new' => $new ?? null,
|
|
]);
|
|
} elseif (in_array($key, $alwaysInclude, true)) {
|
|
$changes[$key] = ['old' => $old, 'new' => $new];
|
|
}
|
|
}
|
|
|
|
return $changes;
|
|
}
|
|
|
|
private function buildDeletedChanges(array $oldValues): array
|
|
{
|
|
$changes = [];
|
|
|
|
foreach ($oldValues as $key => $value) {
|
|
if (is_array($value)) {
|
|
foreach ($value as $item) {
|
|
if (is_array($item)) {
|
|
$itemName = $this->resolveItemName($item);
|
|
foreach ($item as $subKey => $subValue) {
|
|
$changes["{$key}: {$itemName} — {$subKey}"] = ['old' => $subValue];
|
|
}
|
|
} else {
|
|
$changes["{$key}: {$item}"] = ['old' => null];
|
|
}
|
|
}
|
|
} else {
|
|
$changes[$key] = ['old' => $value];
|
|
}
|
|
}
|
|
|
|
return $changes;
|
|
}
|
|
|
|
private function diffArray(array $old, array $new, string $prefix = ''): array
|
|
{
|
|
$changes = [];
|
|
|
|
$isAssociative = ! empty($old) && array_is_list($old) === false;
|
|
|
|
if ($isAssociative) {
|
|
$allKeys = array_unique(array_merge(array_keys($old), array_keys($new)));
|
|
|
|
foreach ($allKeys as $key) {
|
|
$fullKey = "{$prefix}.{$key}";
|
|
|
|
if (isset($old[$key]) && is_array($old[$key]) && isset($new[$key]) && is_array($new[$key])) {
|
|
$nested = $this->diffArray($old[$key], $new[$key], $fullKey);
|
|
$changes = array_merge($changes, $nested);
|
|
} else {
|
|
$oldVal = $old[$key] ?? null;
|
|
$newVal = $new[$key] ?? null;
|
|
|
|
if ($oldVal !== $newVal) {
|
|
$changes[$fullKey] = array_filter([
|
|
'old' => $oldVal ?? null,
|
|
'new' => $newVal ?? null,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$max = max(count($old), count($new));
|
|
|
|
for ($i = 0; $i < $max; $i++) {
|
|
$oldItem = $old[$i] ?? null;
|
|
$newItem = $new[$i] ?? null;
|
|
|
|
if (is_array($oldItem) && is_array($newItem)) {
|
|
$itemName = $this->resolveItemName($newItem);
|
|
$itemPrefix = "{$prefix}: {$itemName}";
|
|
$itemKeys = array_unique(array_merge(array_keys($oldItem), array_keys($newItem)));
|
|
|
|
foreach ($itemKeys as $subKey) {
|
|
$fullKey = "{$itemPrefix} — {$subKey}";
|
|
$oldVal = $oldItem[$subKey] ?? null;
|
|
$newVal = $newItem[$subKey] ?? null;
|
|
|
|
if ($oldVal !== $newVal) {
|
|
$changes[$fullKey] = array_filter([
|
|
'old' => $oldVal ?? null,
|
|
'new' => $newVal ?? null,
|
|
]);
|
|
}
|
|
}
|
|
} elseif ($oldItem !== $newItem) {
|
|
$itemName = $this->resolveItemName(is_array($oldItem) ? $oldItem : (is_array($newItem) ? $newItem : []));
|
|
$changes["{$prefix}: {$itemName}"] = array_filter([
|
|
'old' => $oldItem,
|
|
'new' => $newItem,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $changes;
|
|
}
|
|
|
|
private function formatCurrency(int $value): string
|
|
{
|
|
return 'Rp ' . number_format($value, 0, ',', '.');
|
|
}
|
|
|
|
private function formatDate(?string $date, string $format = 'l, d F Y'): ?string
|
|
{
|
|
return $date ? \Carbon\Carbon::parse($date)->translatedFormat($format) : null;
|
|
}
|
|
|
|
private function formatDateTime(?string $datetime): ?string
|
|
{
|
|
return $datetime ? \Carbon\Carbon::parse($datetime)->translatedFormat('l, d F Y H:i') : null;
|
|
}
|
|
|
|
private function formatBoolean(?bool $value): ?string
|
|
{
|
|
return $value === null ? null : ($value ? 'Ya' : 'Tidak');
|
|
}
|
|
|
|
private function resolveRelation(Model $model, string $relation, string $attribute): ?string
|
|
{
|
|
$related = $model->{$relation};
|
|
|
|
return $related?->{$attribute} ?? null;
|
|
}
|
|
}
|