'date', 'hora_inicio' => 'datetime:H:i', 'hora_fin' => 'datetime:H:i', 'duracion' => 'integer', ]; /** * Relación con Mensaje */ public function mensaje(): BelongsTo { return $this->belongsTo(Mensaje::class); } /** * Scope para filtrar citas pendientes */ public function scopePendiente(Builder $query): Builder { return $query->where('estado', 'pendiente'); } /** * Scope para filtrar citas confirmadas */ public function scopeConfirmada(Builder $query): Builder { return $query->where('estado', 'confirmada'); } /** * Scope para filtrar citas completadas */ public function scopeCompletada(Builder $query): Builder { return $query->where('estado', 'completada'); } /** * Scope para filtrar citas canceladas */ public function scopeCancelada(Builder $query): Builder { return $query->where('estado', 'cancelada'); } /** * Scope para filtrar citas por fecha específica */ public function scopePorFecha(Builder $query, $fecha): Builder { return $query->whereDate('fecha', $fecha); } /** * Scope para filtrar citas entre dos fechas */ public function scopeEntreFechas(Builder $query, $inicio, $fin): Builder { return $query->whereBetween('fecha', [$inicio, $fin]); } /** * Calcular hora_fin basado en hora_inicio + duracion */ public function calcularHoraFin(): string { $horaInicio = Carbon::parse($this->hora_inicio); $horaFin = $horaInicio->addMinutes($this->duracion); $this->hora_fin = $horaFin->format('H:i:s'); return $this->hora_fin; } /** * Obtener estado formateado para mostrar */ public function getEstadoFormateadoAttribute(): string { $estados = [ 'pendiente' => 'Pendiente', 'confirmada' => 'Confirmada', 'completada' => 'Completada', 'cancelada' => 'Cancelada', ]; return $estados[$this->estado] ?? $this->estado; } /** * Obtener hora de inicio formateada */ public function getHoraInicioFormatAttribute(): string { return Carbon::parse($this->hora_inicio)->format('H:i'); } /** * Obtener hora de fin formateada */ public function getHoraFinFormatAttribute(): string { return Carbon::parse($this->hora_fin)->format('H:i'); } /** * Obtener duración formateada (horas y minutos) */ public function getDuracionFormatAttribute(): string { $horas = floor($this->duracion / 60); $minutos = $this->duracion % 60; if ($horas > 0 && $minutos > 0) { return "{$horas}h {$minutos}min"; } elseif ($horas > 0) { return "{$horas}h"; } else { return "{$minutos}min"; } } /** * Verificar si la cita está activa (no cancelada ni completada) */ public function isActiva(): bool { return in_array($this->estado, ['pendiente', 'confirmada']); } /** * Cambiar estado de la cita */ public function cambiarEstado(string $nuevoEstado): bool { $estadosValidos = ['pendiente', 'confirmada', 'completada', 'cancelada']; if (! in_array($nuevoEstado, $estadosValidos)) { return false; } return $this->update(['estado' => $nuevoEstado]); } }