'date', 'actual_start_time' => 'datetime', 'actual_end_time' => 'datetime', 'dumpsite_arrival_time' => 'datetime', 'dumpsite_departure_time' => 'datetime', 'is_detouring' => 'boolean', 'current_load_kg' => 'integer', ]; } public function getRouteKeyName(): string { return 'uuid'; } public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() ->logOnly(['status', 'team_id', 'truck_id', 'scheduled_date', 'total_load_kg']) ->logOnlyDirty() ->dontSubmitEmptyLogs() ->useLogName('trip'); } protected static function booted(): void { static::creating(function (self $t): void { if (empty($t->uuid)) { $t->uuid = (string) Str::uuid(); } if (empty($t->tenant_id)) { if ($t->team_id) { $t->tenant_id = $t->team?->tenant_id; } if (empty($t->tenant_id) && $t->route_id) { $t->tenant_id = $t->route?->tenant_id; } } if (empty($t->trip_number)) { $date = ($t->scheduled_date ? Carbon::parse($t->scheduled_date) : now())->format('Ymd'); $seq = self::where('trip_number', 'like', "TRIP-{$date}-%")->count() + 1; $t->trip_number = sprintf('TRIP-%s-%03d', $date, $seq); } }); } public function route(): BelongsTo { return $this->belongsTo(Route::class); } public function team(): BelongsTo { return $this->belongsTo(CollectionTeam::class, 'team_id'); } public function truck(): BelongsTo { return $this->belongsTo(Truck::class); } public function dumpsite(): BelongsTo { return $this->belongsTo(Dumpsite::class); } public function stops(): HasMany { return $this->hasMany(TripStop::class)->orderBy('sequence'); } public function timelineEvents(): HasMany { return $this->hasMany(TripTimelineEvent::class)->orderBy('event_at'); } public function dumpsiteReleases(): HasMany { return $this->hasMany(DumpsiteRelease::class); } public function collectionLogs(): HasMany { return $this->hasMany(CollectionLog::class, 'trip_id'); } }