128 lines
3.9 KiB
PHP
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,
|
|
]);
|
|
}
|
|
}
|