Car-Repairs-Shop/app/Models/PartHistory.php
sackey e839d40a99
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Initial commit
2025-07-30 17:15:50 +00:00

128 lines
3.9 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PartHistory extends Model
{
use HasFactory;
protected $fillable = [
'part_id',
'event_type',
'old_values',
'new_values',
'quantity_change',
'quantity_before',
'quantity_after',
'cost_before',
'cost_after',
'reference_type',
'reference_id',
'notes',
'ip_address',
'user_agent',
'created_by',
];
protected $casts = [
'old_values' => 'array',
'new_values' => 'array',
'quantity_change' => 'integer',
'quantity_before' => 'integer',
'quantity_after' => 'integer',
'cost_before' => 'decimal:2',
'cost_after' => 'decimal:2',
];
// Event types
const EVENT_CREATED = 'created';
const EVENT_UPDATED = 'updated';
const EVENT_STOCK_IN = 'stock_in';
const EVENT_STOCK_OUT = 'stock_out';
const EVENT_ADJUSTMENT = 'adjustment';
const EVENT_PRICE_CHANGE = 'price_change';
const EVENT_SUPPLIER_CHANGE = 'supplier_change';
const EVENT_DELETED = 'deleted';
const EVENT_RESTORED = 'restored';
public function part(): BelongsTo
{
return $this->belongsTo(Part::class);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function getEventColorAttribute(): string
{
return match($this->event_type) {
self::EVENT_CREATED => 'green',
self::EVENT_UPDATED => 'blue',
self::EVENT_STOCK_IN => 'green',
self::EVENT_STOCK_OUT => 'red',
self::EVENT_ADJUSTMENT => 'yellow',
self::EVENT_PRICE_CHANGE => 'purple',
self::EVENT_SUPPLIER_CHANGE => 'orange',
self::EVENT_DELETED => 'red',
self::EVENT_RESTORED => 'green',
default => 'gray',
};
}
public function getEventIconAttribute(): string
{
return match($this->event_type) {
self::EVENT_CREATED => 'plus-circle',
self::EVENT_UPDATED => 'pencil',
self::EVENT_STOCK_IN => 'arrow-down',
self::EVENT_STOCK_OUT => 'arrow-up',
self::EVENT_ADJUSTMENT => 'cog-6-tooth',
self::EVENT_PRICE_CHANGE => 'currency-dollar',
self::EVENT_SUPPLIER_CHANGE => 'building-office',
self::EVENT_DELETED => 'trash',
self::EVENT_RESTORED => 'arrow-path',
default => 'information-circle',
};
}
public function getFormattedQuantityChangeAttribute(): string
{
if ($this->quantity_change === null) {
return '';
}
$prefix = $this->quantity_change > 0 ? '+' : '';
return $prefix . number_format($this->quantity_change);
}
public static function logEvent(
int $partId,
string $eventType,
array $options = []
): self {
return self::create([
'part_id' => $partId,
'event_type' => $eventType,
'old_values' => $options['old_values'] ?? null,
'new_values' => $options['new_values'] ?? null,
'quantity_change' => $options['quantity_change'] ?? null,
'quantity_before' => $options['quantity_before'] ?? null,
'quantity_after' => $options['quantity_after'] ?? null,
'cost_before' => $options['cost_before'] ?? null,
'cost_after' => $options['cost_after'] ?? null,
'reference_type' => $options['reference_type'] ?? null,
'reference_id' => $options['reference_id'] ?? null,
'notes' => $options['notes'] ?? null,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'created_by' => auth()->id() ?? 1,
]);
}
}