'Maintenance', 'repair' => 'Repair', 'inspection' => 'Inspection', 'estimate' => 'Estimate', 'pickup' => 'Pickup', 'delivery' => 'Delivery' ]; public $durationOptions = [ 30 => '30 minutes', 60 => '1 hour', 90 => '1.5 hours', 120 => '2 hours', 180 => '3 hours', 240 => '4 hours', 300 => '5 hours', 360 => '6 hours', 480 => '8 hours' ]; protected $rules = [ 'customer_id' => 'required|exists:customers,id', 'vehicle_id' => 'required|exists:vehicles,id', 'assigned_technician_id' => 'nullable|exists:technicians,id', 'scheduled_date' => 'required|date|after_or_equal:today', 'scheduled_time' => 'required|date_format:H:i', 'estimated_duration_minutes' => 'required|integer|min:15|max:480', 'appointment_type' => 'required|in:maintenance,repair,inspection,estimate,pickup,delivery', 'service_requested' => 'required|string|max:1000', 'customer_notes' => 'nullable|string|max:1000', 'internal_notes' => 'nullable|string|max:1000' ]; public function mount($appointment = null) { $this->customers = Customer::orderBy('first_name')->get(); $this->technicians = Technician::where('status', 'active')->orderBy('first_name')->get(); if ($appointment) { $this->appointment = $appointment; $this->editing = true; $this->loadAppointmentData(); } else { $this->scheduled_date = now()->addDay()->format('Y-m-d'); $this->scheduled_time = '09:00'; } } public function loadAppointmentData() { $this->customer_id = $this->appointment->customer_id; $this->vehicle_id = $this->appointment->vehicle_id; $this->assigned_technician_id = $this->appointment->assigned_technician_id; $this->scheduled_date = $this->appointment->scheduled_datetime->format('Y-m-d'); $this->scheduled_time = $this->appointment->scheduled_datetime->format('H:i'); $this->estimated_duration_minutes = $this->appointment->estimated_duration_minutes; $this->appointment_type = $this->appointment->appointment_type; $this->service_requested = $this->appointment->service_requested; $this->customer_notes = $this->appointment->customer_notes; $this->internal_notes = $this->appointment->internal_notes; $this->loadVehicles(); } public function updatedCustomerId() { $this->vehicle_id = ''; $this->loadVehicles(); } public function updatedScheduledDate() { $this->checkTimeSlotAvailability(); } public function updatedScheduledTime() { $this->checkTimeSlotAvailability(); } public function updatedAssignedTechnicianId() { $this->checkTimeSlotAvailability(); } public function loadVehicles() { if ($this->customer_id) { $this->vehicles = Vehicle::where('customer_id', $this->customer_id)->get(); } else { $this->vehicles = []; } } public function checkTimeSlotAvailability() { if (!$this->scheduled_date || !$this->scheduled_time || !$this->assigned_technician_id) { return; } $scheduledDateTime = Carbon::parse($this->scheduled_date . ' ' . $this->scheduled_time); $endDateTime = $scheduledDateTime->copy()->addMinutes($this->estimated_duration_minutes); // Check for conflicts $conflicts = Appointment::where('assigned_technician_id', $this->assigned_technician_id) ->where('status', '!=', 'cancelled') ->where(function ($query) use ($scheduledDateTime, $endDateTime) { $query->whereBetween('scheduled_datetime', [$scheduledDateTime, $endDateTime]) ->orWhere(function ($q) use ($scheduledDateTime, $endDateTime) { $q->where('scheduled_datetime', '<=', $scheduledDateTime) ->whereRaw('DATE_ADD(scheduled_datetime, INTERVAL estimated_duration_minutes MINUTE) > ?', [$scheduledDateTime]); }); }); if ($this->editing && $this->appointment) { $conflicts->where('id', '!=', $this->appointment->id); } if ($conflicts->exists()) { $this->addError('scheduled_time', 'This time slot conflicts with another appointment for the selected technician.'); } else { $this->resetErrorBag('scheduled_time'); } } public function save() { $this->validate(); $scheduledDateTime = Carbon::parse($this->scheduled_date . ' ' . $this->scheduled_time); $data = [ 'customer_id' => $this->customer_id, 'vehicle_id' => $this->vehicle_id, 'assigned_technician_id' => $this->assigned_technician_id ?: null, 'scheduled_datetime' => $scheduledDateTime, 'estimated_duration_minutes' => $this->estimated_duration_minutes, 'appointment_type' => $this->appointment_type, 'service_requested' => $this->service_requested, 'customer_notes' => $this->customer_notes, 'internal_notes' => $this->internal_notes, 'status' => 'scheduled' ]; if ($this->editing && $this->appointment) { $this->appointment->update($data); session()->flash('message', 'Appointment updated successfully!'); } else { Appointment::create($data); session()->flash('message', 'Appointment scheduled successfully!'); } $this->dispatch('appointment-saved'); $this->closeModal(); } public function closeModal() { $this->showModal = false; $this->dispatch('close-appointment-form'); } public function render() { return view('livewire.appointments.form'); } }