Files
star-erp/app/Modules/Inventory/Models/Product.php
2026-03-02 10:19:38 +08:00

143 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Modules\Inventory\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Product extends Model
{
use HasFactory, LogsActivity, SoftDeletes;
protected $fillable = [
'code',
'barcode',
'name',
'external_pos_id',
'category_id',
'brand',
'specification',
'base_unit_id',
'large_unit_id',
'conversion_rate',
'purchase_unit_id',
'location',
'cost_price',
'price',
'member_price',
'wholesale_price',
'is_active',
];
protected $casts = [
'conversion_rate' => 'decimal:4',
'is_active' => 'boolean',
];
/**
* 取得該商品所屬的分類。
*/
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function baseUnit(): BelongsTo
{
return $this->belongsTo(Unit::class, 'base_unit_id');
}
public function largeUnit(): BelongsTo
{
return $this->belongsTo(Unit::class, 'large_unit_id');
}
public function purchaseUnit(): BelongsTo
{
return $this->belongsTo(Unit::class, 'purchase_unit_id');
}
public function inventories(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(Inventory::class);
}
public function transactions(): HasMany
{
return $this->hasMany(InventoryTransaction::class);
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logAll()
->logOnlyDirty()
->dontSubmitEmptyLogs();
}
public function tapActivity(\Spatie\Activitylog\Contracts\Activity $activity, string $eventName)
{
// 核心:轉換為陣列以避免 Indirect modification error
$properties = $activity->properties instanceof \Illuminate\Support\Collection
? $activity->properties->toArray()
: $activity->properties;
$snapshot = $properties['snapshot'] ?? [];
// 始終對自身名稱進行快照以便於上下文顯示(這樣日誌總是顯示 "可樂"
$snapshot['name'] = $this->name;
$properties['snapshot'] = $snapshot;
// 全域 ID 轉名稱邏輯
$resolver = function (&$data) use (&$snapshot) {
if (empty($data) || !is_array($data)) return;
// 處理分類名稱
if (isset($data['category_id']) && is_numeric($data['category_id'])) {
$categoryName = Category::find($data['category_id'])?->name;
$data['category_id'] = $categoryName;
if (!isset($snapshot['category_name']) && $categoryName) {
$snapshot['category_name'] = $categoryName;
}
}
// 處理單位名稱
$unitFields = ['base_unit_id', 'large_unit_id', 'purchase_unit_id'];
foreach ($unitFields as $field) {
if (isset($data[$field]) && is_numeric($data[$field])) {
$unitName = Unit::find($data[$field])?->name;
$data[$field] = $unitName;
$nameKey = str_replace('_id', '_name', $field);
if (!isset($snapshot[$nameKey]) && $unitName) {
$snapshot[$nameKey] = $unitName;
}
}
}
};
if (isset($properties['attributes'])) $resolver($properties['attributes']);
if (isset($properties['old'])) $resolver($properties['old']);
// 因為 resolver 內部可能更新了 snapshot所以再覆寫一次
$properties['snapshot'] = $snapshot;
$activity->properties = $properties;
}
public function warehouses(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
{
return $this->belongsToMany(Warehouse::class, 'inventories')
->withPivot(['quantity', 'safety_stock', 'location'])
->withTimestamps();
}
}