physiotherapy-clinic/app/Http/Controllers/Api/AppointmentController.php

171 lines
5.5 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreAppointmentRequest;
use App\Http\Requests\UpdateAppointmentRequest;
use App\Http\Resources\AppointmentResource;
use App\Models\Appointment;
use App\Services\AppointmentService;
use Illuminate\Http\Request;
class AppointmentController extends Controller
{
protected $appointmentService;
public function __construct(AppointmentService $appointmentService)
{
$this->appointmentService = $appointmentService;
}
public function index(Request $request)
{
$query = Appointment::with(['patient', 'user']);
if ($request->has('patient_id')) {
$query->where('patient_id', $request->patient_id);
}
if ($request->has('therapist_id')) {
$query->where('user_id', $request->therapist_id);
}
if ($request->has('status')) {
$query->where('status', $request->status);
}
if ($request->has('date_from')) {
$query->whereDate('appointment_date', '>=', $request->date_from);
}
if ($request->has('date_to')) {
$query->whereDate('appointment_date', '<=', $request->date_to);
}
if ($request->has('date')) {
$query->whereDate('appointment_date', $request->date);
}
$appointments = $query->orderBy('appointment_date')->paginate($request->per_page ?? 20);
return AppointmentResource::collection($appointments);
}
public function store(StoreAppointmentRequest $request)
{
$data = $request->validated();
// Check for conflicts
$appointmentDate = \Carbon\Carbon::parse($data['appointment_date']);
if ($this->appointmentService->hasConflict($data['therapist_id'], $appointmentDate, $data['duration_minutes'])) {
return response()->json([
'message' => 'Therapist has a conflicting appointment at this time',
], 422);
}
if ($this->appointmentService->hasPatientConflict($data['patient_id'], $appointmentDate, $data['duration_minutes'])) {
return response()->json([
'message' => 'Patient has a conflicting appointment at this time',
], 422);
}
$appointment = Appointment::create([
'patient_id' => $data['patient_id'],
'user_id' => $data['therapist_id'],
'appointment_date' => $data['appointment_date'],
'duration_minutes' => $data['duration_minutes'],
'notes' => $data['notes'] ?? null,
]);
// Generate reminders
$reminderService = new \App\Services\ReminderService();
$reminderService->generateReminders($appointment);
return new AppointmentResource($appointment);
}
public function show(Appointment $appointment)
{
return new AppointmentResource($appointment);
}
public function update(UpdateAppointmentRequest $request, Appointment $appointment)
{
$data = $request->validated();
// Check for conflicts if date/therapist changed
if (isset($data['appointment_date']) || isset($data['therapist_id'])) {
$newDate = isset($data['appointment_date'])
? \Carbon\Carbon::parse($data['appointment_date'])
: $appointment->appointment_date;
$newTherapistId = $data['therapist_id'] ?? $appointment->user_id;
$duration = $data['duration_minutes'] ?? $appointment->duration_minutes;
if ($this->appointmentService->hasConflict($newTherapistId, $newDate, $duration, $appointment->id)) {
return response()->json([
'message' => 'Therapist has a conflicting appointment at this time',
], 422);
}
}
$appointment->update([
'patient_id' => $data['patient_id'],
'user_id' => $data['therapist_id'],
'appointment_date' => $data['appointment_date'],
'duration_minutes' => $data['duration_minutes'],
'status' => $data['status'],
'notes' => $data['notes'] ?? null,
'cancellation_reason' => $data['cancellation_reason'] ?? null,
]);
if ($data['status'] === 'cancelled') {
$appointment->cancelled_by = auth()->id();
$appointment->cancelled_at = now();
$appointment->save();
}
return new AppointmentResource($appointment);
}
public function destroy(Appointment $appointment)
{
$appointment->delete();
return response()->json(['message' => 'Appointment deleted successfully']);
}
public function calendar(Request $request)
{
$request->validate([
'start' => 'required|date',
'end' => 'required|date|after_or_equal:start',
]);
$feed = $this->appointmentService->getCalendarFeed(
$request->start,
$request->end,
$request->therapist_id
);
return response()->json($feed);
}
public function availableSlots(Request $request)
{
$request->validate([
'therapist_id' => 'required|exists:users,id',
'date' => 'required|date',
'duration' => 'nullable|integer|min:15',
]);
$slots = $this->appointmentService->getAvailableSlots(
$request->therapist_id,
$request->date,
$request->duration ?? 60
);
return response()->json(['slots' => $slots]);
}
}