'Mở', 'pending' => 'Đang xử lý', 'resolved' => 'Đã giải quyết', 'closed' => 'Đã đóng', ]; public const PRIORITY_LABELS = [ 'low' => 'Thấp', 'medium' => 'Trung bình', 'high' => 'Cao', ]; public const ROOM_LABELS = [ 'technical' => 'Kỹ thuật', 'sales' => 'Bán hàng', ]; protected $table = 'ticket'; protected $fillable = [ 'uuid', 'ticket_num', 'subject', 'customer_id', 'description', 'status', 'room', 'data', 'gallery', ]; protected $casts = [ 'gallery' => 'array', ]; public function priority(): ?string { $data = is_string($this->data) ? json_decode($this->data, true) : $this->data; return is_array($data) ? ($data['priority'] ?? null) : null; } /** * @return Collection */ public function statusHistory(): Collection { return ActivityLog::query() ->where('subject_type', self::class) ->where('subject_id', $this->id) ->whereIn('event', ['created', 'updated']) ->whereNotNull('new_values->status') ->latest('id') ->get(['old_values', 'new_values', 'causer_type', 'causer_name', 'created_at']) ->map(fn (ActivityLog $log) => [ 'from' => $log->old_values['status'] ?? null, 'to' => $log->new_values['status'], 'causer_type' => $log->causer_type, 'causer_name' => $log->causer_name, 'created_at' => $log->created_at, ]); } public function roomLabel(): ?string { return $this->room ? (self::ROOM_LABELS[$this->room] ?? $this->room) : null; } public function customer() { return $this->belongsTo(\App\Models\Customer::class); } public function reply() { return $this->hasMany(\App\Models\TicketReply::class,'ticket_id','id'); } }