Files
bikeservice/backend/app/Http/Controllers/ServiceRequestController.php
2025-10-08 19:48:48 +02:00

369 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\ServiceRequest;
use App\Models\Setting;
use App\Models\Communication;
use App\Mail\ServiceRequestNotification;
use App\Mail\PickupConfirmation;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
class ServiceRequestController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(): JsonResponse
{
try {
$requests = ServiceRequest::with('communications')
->orderBy('created_at', 'desc')
->get();
return response()->json($requests);
} catch (\Exception $e) {
return response()->json([
'message' => 'Service aanvragen ophalen mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): JsonResponse
{
try {
$validated = $request->validate([
'name' => 'required|string|max:255',
'address' => 'required|string',
'place' => 'required|string|max:255',
'email' => 'nullable|email|max:255',
'phone' => 'nullable|string|max:20',
'repair_description' => 'required|string',
'requested_date' => 'required|date|after:today',
'requested_time' => 'required|date_format:H:i',
], [
'name.required' => 'Naam is verplicht',
'name.max' => 'Naam mag maximaal 255 karakters bevatten',
'address.required' => 'Adres is verplicht',
'place.required' => 'Plaats is verplicht',
'place.max' => 'Plaats mag maximaal 255 karakters bevatten',
'email.email' => 'E-mailadres moet een geldig e-mailadres zijn',
'email.max' => 'E-mailadres mag maximaal 255 karakters bevatten',
'phone.max' => 'Telefoonnummer mag maximaal 20 karakters bevatten',
'repair_description.required' => 'Reparatie beschrijving is verplicht',
'requested_date.required' => 'Gewenste datum is verplicht',
'requested_date.after' => 'Gewenste datum moet in de toekomst liggen',
'requested_time.required' => 'Gewenste tijd is verplicht',
'requested_time.date_format' => 'Gewenste tijd moet een geldig tijdformaat hebben (HH:MM)',
]);
// Check if at least one contact method is provided
if (empty($validated['email']) && empty($validated['phone'])) {
throw ValidationException::withMessages([
'contact' => 'Geef alstublieft een e-mailadres of telefoonnummer op.'
]);
}
$serviceRequest = ServiceRequest::create($validated);
// Send notification email to admin
$this->sendNotificationEmail($serviceRequest);
return response()->json($serviceRequest, 201);
} catch (ValidationException $e) {
return response()->json([
'message' => 'Validatie mislukt',
'errors' => $e->errors()
], 422);
} catch (\Exception $e) {
return response()->json([
'message' => 'Service aanvraag aanmaken mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(ServiceRequest $serviceRequest): JsonResponse
{
try {
$serviceRequest->load('communications');
return response()->json($serviceRequest);
} catch (\Exception $e) {
return response()->json([
'message' => 'Service aanvraag ophalen mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, ServiceRequest $serviceRequest): JsonResponse
{
try {
$validated = $request->validate([
'actual_repair_date' => 'nullable|date|after:today',
'actual_repair_time' => 'nullable|date_format:H:i',
'status' => 'nullable|in:pending,confirmed,mail_sent,completed,cancelled',
], [
'actual_repair_date.after' => 'Werkelijke reparatie datum moet in de toekomst liggen',
'actual_repair_time.date_format' => 'Werkelijke reparatie tijd moet een geldig tijdformaat hebben (HH:MM)',
'status.in' => 'Status moet een van de volgende waarden hebben: in afwachting, bevestigd, bevestigd mail verstuurd, voltooid, geannuleerd',
]);
$serviceRequest->update($validated);
return response()->json($serviceRequest);
} catch (ValidationException $e) {
return response()->json([
'message' => 'Validatie mislukt',
'errors' => $e->errors()
], 422);
} catch (\Exception $e) {
return response()->json([
'message' => 'Service aanvraag bijwerken mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(ServiceRequest $serviceRequest): JsonResponse
{
try {
$serviceRequest->delete();
return response()->json([
'message' => 'Service aanvraag succesvol verwijderd'
]);
} catch (\Exception $e) {
return response()->json([
'message' => 'Service aanvraag verwijderen mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Send email to customer
*/
public function sendEmail(Request $request, ServiceRequest $serviceRequest): JsonResponse
{
try {
$validated = $request->validate([
'message' => 'required|string',
], [
'message.required' => 'Bericht is verplicht',
]);
if (empty($serviceRequest->email)) {
return response()->json([
'message' => 'Geen e-mailadres beschikbaar voor deze service aanvraag'
], 400);
}
// Store communication record
$communication = Communication::create([
'service_request_id' => $serviceRequest->id,
'type' => 'email',
'message' => $validated['message'],
'direction' => 'admin_to_customer',
'recipient' => $serviceRequest->email,
'sent_at' => now(),
]);
// TODO: Implement actual email sending logic
// For now, we'll just log it
Log::info('E-mail verzonden naar klant', [
'service_request_id' => $serviceRequest->id,
'email' => $serviceRequest->email,
'message' => $validated['message']
]);
return response()->json([
'message' => 'E-mail succesvol verzonden',
'communication' => $communication
]);
} catch (\Exception $e) {
return response()->json([
'message' => 'E-mail verzenden mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Send SMS to customer
*/
public function sendSms(Request $request, ServiceRequest $serviceRequest): JsonResponse
{
try {
$validated = $request->validate([
'message' => 'required|string',
], [
'message.required' => 'Bericht is verplicht',
]);
if (empty($serviceRequest->phone)) {
return response()->json([
'message' => 'Geen telefoonnummer beschikbaar voor deze service aanvraag'
], 400);
}
// Store communication record
$communication = Communication::create([
'service_request_id' => $serviceRequest->id,
'type' => 'sms',
'message' => $validated['message'],
'direction' => 'admin_to_customer',
'recipient' => $serviceRequest->phone,
'sent_at' => now(),
]);
// TODO: Implement actual SMS sending logic
// For now, we'll just log it
Log::info('SMS verzonden naar klant', [
'service_request_id' => $serviceRequest->id,
'phone' => $serviceRequest->phone,
'message' => $validated['message']
]);
return response()->json([
'message' => 'SMS succesvol verzonden',
'communication' => $communication
]);
} catch (\Exception $e) {
return response()->json([
'message' => 'SMS verzenden mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Send pickup confirmation email to customer
*/
public function sendPickupConfirmation(ServiceRequest $serviceRequest): JsonResponse
{
try {
if (empty($serviceRequest->email)) {
return response()->json([
'message' => 'Geen e-mailadres beschikbaar voor deze service aanvraag'
], 400);
}
if (empty($serviceRequest->actual_repair_date) || empty($serviceRequest->actual_repair_time)) {
return response()->json([
'message' => 'Werkelijke reparatie datum en tijd zijn vereist'
], 400);
}
// Get the custom message from settings
$customMessage = Setting::getValue('pickup_confirmation_email_text', 'Uw fiets is klaar en kan worden opgehaald.');
// Format the pickup date and time
$pickupDate = \Carbon\Carbon::parse($serviceRequest->actual_repair_date)->format('d-m-Y');
$pickupTime = $serviceRequest->actual_repair_time;
// Send email
Mail::to($serviceRequest->email)->send(
new PickupConfirmation(
$serviceRequest,
$customMessage,
$pickupDate,
$pickupTime
)
);
// Update status to 'mail_sent'
$serviceRequest->update(['status' => 'mail_sent']);
// Store communication record
$communication = Communication::create([
'service_request_id' => $serviceRequest->id,
'type' => 'email',
'message' => 'Ophaalbevestiging verzonden - Datum: ' . $pickupDate . ', Tijd: ' . $pickupTime,
'direction' => 'admin_to_customer',
'recipient' => $serviceRequest->email,
'sent_at' => now(),
]);
Log::info('Ophaalbevestiging e-mail verzonden naar klant', [
'service_request_id' => $serviceRequest->id,
'email' => $serviceRequest->email,
'pickup_date' => $pickupDate,
'pickup_time' => $pickupTime
]);
return response()->json([
'message' => 'Ophaalbevestiging succesvol verzonden',
'communication' => $communication,
'service_request' => $serviceRequest->fresh()
]);
} catch (\Exception $e) {
return response()->json([
'message' => 'Ophaalbevestiging verzenden mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Get communication history
*/
public function communications(ServiceRequest $serviceRequest): JsonResponse
{
try {
$communications = $serviceRequest->communications()
->orderBy('created_at', 'desc')
->get();
return response()->json($communications);
} catch (\Exception $e) {
return response()->json([
'message' => 'Communicatie ophalen mislukt',
'error' => $e->getMessage()
], 500);
}
}
/**
* Send notification email to admin
*/
private function sendNotificationEmail(ServiceRequest $serviceRequest): void
{
try {
$adminEmail = Setting::getValue('admin_notification_email');
if ($adminEmail) {
// Send email to admin
Mail::to($adminEmail)->send(new ServiceRequestNotification($serviceRequest));
Log::info('Notificatie e-mail verzonden naar beheerder', [
'service_request_id' => $serviceRequest->id,
'admin_email' => $adminEmail,
'customer_name' => $serviceRequest->name
]);
}
} catch (\Exception $e) {
Log::error('Notificatie e-mail naar beheerder verzenden mislukt', [
'error' => $e->getMessage(),
'service_request_id' => $serviceRequest->id
]);
}
}
}