hasTag(Tag $tag) * @method static TimeEntryFactory factory() */ class TimeEntry extends Model implements AuditableContract { use ComputedAttributes; use CustomAuditable; /** @use HasFactory */ use HasFactory; use HasUuids; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'description' => 'string', 'start' => 'datetime', 'end' => 'datetime', 'billable' => 'bool', 'tags' => 'array', 'billable_rate' => 'int', 'is_imported' => 'bool', 'still_active_email_sent_at' => 'datetime', ]; /** * The attributes that are computed. (f.e. for performance reasons) * These attributes can be regenerated at any time. * * @var string[] */ protected array $computed = [ 'billable_rate', ]; public function getBillableRateComputed(): ?int { return app(BillableRateService::class)->getBillableRateForTimeEntry($this); } public function getDuration(): ?CarbonInterval { return $this->end === null ? null : $this->start->diffAsCarbonInterval($this->end); } /** * @param Builder $builder */ public function scopeHasTag(Builder $builder, Tag $tag): void { $builder->whereJsonContains('tags', $tag->getKey()); } /** * @return BelongsTo */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } /** * @return BelongsTo */ public function member(): BelongsTo { return $this->belongsTo(Member::class, 'member_id'); } /** * @return BelongsTo */ public function organization(): BelongsTo { return $this->belongsTo(Organization::class, 'organization_id'); } /** * @return BelongsTo */ public function project(): BelongsTo { return $this->belongsTo(Project::class, 'project_id'); } /** * @return BelongsTo */ public function task(): BelongsTo { return $this->belongsTo(Task::class, 'task_id'); } /** * This relation can be reconstructed via the task relation. It is only here for performance reasons. * * @return BelongsTo */ public function client(): BelongsTo { return $this->belongsTo(Client::class, 'client_id'); } }