|string> */ public function rules(): array { return [ 'deceased' => 'required|array', 'deceased.last_name' => ['required', 'string', 'max:191'], 'deceased.first_name' => ['nullable', 'string', 'max:191'], 'deceased.birth_date' => ['nullable', 'date'], 'deceased.death_date' => ['nullable', 'date', 'after_or_equal:deceased.birth_date'], 'deceased.place_of_death' => ['nullable', 'string', 'max:255'], 'deceased.notes' => ['nullable', 'string'], 'client' => 'required|array', 'client.name' => ['required', 'string', 'max:255'], 'client.vat_number' => ['nullable', 'string', 'max:32'], 'client.siret' => ['nullable', 'string', 'max:20'], 'client.email' => ['nullable', 'email', 'max:191'], 'client.phone' => ['nullable', 'string', 'max:50'], 'client.billing_address_line1' => ['nullable', 'string', 'max:255'], 'client.billing_address_line2' => ['nullable', 'string', 'max:255'], 'client.billing_postal_code' => ['nullable', 'string', 'max:20'], 'client.billing_city' => ['nullable', 'string', 'max:191'], 'client.billing_country_code' => ['nullable', 'string', 'size:2'], 'client.notes' => ['nullable', 'string'], 'contact' => 'nullable|array', 'contact.first_name' => ['nullable', 'string', 'max:191'], 'contact.last_name' => ['nullable', 'string', 'max:191'], 'contact.email' => ['nullable', 'email', 'max:191'], 'contact.phone' => ['nullable', 'string', 'max:50'], 'contact.role' => ['nullable', 'string', 'max:191'], 'location' => 'nullable|array', 'location.name' => ['nullable', 'string', 'max:255'], 'location.address' => ['nullable', 'string', 'max:255'], 'location.city' => ['nullable', 'string', 'max:191'], 'location.postal_code' => ['nullable', 'string', 'max:20'], 'location.country_code' => ['nullable', 'string', 'size:2'], 'location.access_instructions' => ['nullable', 'string'], 'location.notes' => ['nullable', 'string'], 'documents' => 'nullable|array', 'documents.*.file' => ['required', 'file'], 'documents.*.name' => ['required', 'string', 'max:255'], 'documents.*.description' => ['nullable', 'string'], 'intervention' => 'required|array', 'intervention.type' => ['required', Rule::in([ 'thanatopraxie', 'toilette_mortuaire', 'exhumation', 'retrait_pacemaker', 'retrait_bijoux', 'autre' ])], 'intervention.scheduled_at' => ['nullable', 'date_format:Y-m-d H:i:s'], 'intervention.duration_min' => ['nullable', 'integer', 'min:0'], 'intervention.status' => ['sometimes', Rule::in([ 'demande', 'planifie', 'en_cours', 'termine', 'annule' ])], 'intervention.assigned_practitioner_id' => ['nullable', 'exists:thanatopractitioners,id'], 'intervention.order_giver' => ['nullable', 'string', 'max:255'], 'intervention.notes' => ['nullable', 'string'], 'intervention.created_by' => ['nullable', 'exists:users,id'] ]; } /** * Get custom error messages for validator errors. */ public function messages(): array { $messages = [ 'deceased.required' => 'Les informations du défunt sont obligatoires.', 'deceased.last_name.required' => 'Le nom de famille du défunt est obligatoire.', 'deceased.last_name.max' => 'Le nom de famille ne peut pas dépasser 191 caractères.', 'deceased.first_name.max' => 'Le prénom ne peut pas dépasser 191 caractères.', 'deceased.death_date.after_or_equal' => 'La date de décès doit être postérieure ou égale à la date de naissance.', 'deceased.place_of_death.max' => 'Le lieu de décès ne peut pas dépasser 255 caractères.', 'client.required' => 'Les informations du client sont obligatoires.', 'client.name.required' => 'Le nom du client est obligatoire.', 'client.name.max' => 'Le nom du client ne peut pas dépasser 255 caractères.', 'client.vat_number.max' => 'Le numéro de TVA ne peut pas dépasser 32 caractères.', 'client.siret.max' => 'Le SIRET ne peut pas dépasser 20 caractères.', 'client.email.email' => 'L\'adresse email doit être valide.', 'client.email.max' => 'L\'adresse email ne peut pas dépasser 191 caractères.', 'client.phone.max' => 'Le téléphone ne peut pas dépasser 50 caractères.', 'client.billing_address_line1.max' => 'L\'adresse ne peut pas dépasser 255 caractères.', 'client.billing_postal_code.max' => 'Le code postal ne peut pas dépasser 20 caractères.', 'client.billing_city.max' => 'La ville ne peut pas dépasser 191 caractères.', 'client.billing_country_code.size' => 'Le code pays doit contenir 2 caractères.', 'client.is_active.boolean' => 'Le statut actif doit être vrai ou faux.', 'contact.first_name.max' => 'Le prénom ne peut pas dépasser 191 caractères.', 'contact.last_name.max' => 'Le nom ne peut pas dépasser 191 caractères.', 'contact.email.email' => 'L\'adresse email doit être valide.', 'contact.email.max' => 'L\'adresse email ne peut pas dépasser 191 caractères.', 'contact.phone.max' => 'Le téléphone ne peut pas dépasser 50 caractères.', 'contact.role.max' => 'Le rôle ne peut pas dépasser 191 caractères.', 'intervention.required' => 'Les informations de l\'intervention sont obligatoires.', 'intervention.type.required' => 'Le type d\'intervention est obligatoire.', 'intervention.type.in' => 'Le type d\'intervention est invalide.', 'intervention.scheduled_at.date_format' => 'Le format de la date programmée est invalide.', 'intervention.duration_min.integer' => 'La durée doit être un nombre entier.', 'intervention.duration_min.min' => 'La durée ne peut pas être négative.', 'intervention.status.in' => 'Le statut de l\'intervention est invalide.', 'intervention.assigned_practitioner_id.exists' => 'Le praticien sélectionné est invalide.', 'intervention.order_giver.max' => 'Le donneur d\'ordre ne peut pas dépasser 255 caractères.', 'intervention.created_by.exists' => 'L\'utilisateur créateur est invalide.' ]; // Add document-specific messages $messages = array_merge($messages, [ 'documents.array' => 'Les documents doivent être un tableau.', 'documents.*.file.required' => 'Chaque document doit avoir un fichier.', 'documents.*.name.required' => 'Le nom du document est obligatoire.', 'documents.*.name.max' => 'Le nom du document ne peut pas dépasser 255 caractères.', ]); return $messages; } /** * Handle a failed validation attempt. */ protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator) { $errors = $validator->errors(); // Group errors by step for better UX $groupedErrors = [ 'deceased' => [], 'client' => [], 'contact' => [], 'location' => [], 'documents' => [], 'intervention' => [], 'global' => [] ]; foreach ($errors->messages() as $field => $messages) { if (str_starts_with($field, 'deceased.')) { $groupedErrors['deceased'] = array_merge($groupedErrors['deceased'], $messages); } elseif (str_starts_with($field, 'client.')) { $groupedErrors['client'] = array_merge($groupedErrors['client'], $messages); } elseif (str_starts_with($field, 'contact.')) { $groupedErrors['contact'] = array_merge($groupedErrors['contact'], $messages); } elseif (str_starts_with($field, 'location.')) { $groupedErrors['location'] = array_merge($groupedErrors['location'], $messages); } elseif (str_starts_with($field, 'documents.')) { $groupedErrors['documents'] = array_merge($groupedErrors['documents'], $messages); } elseif (str_starts_with($field, 'intervention.')) { $groupedErrors['intervention'] = array_merge($groupedErrors['intervention'], $messages); } else { $groupedErrors['global'] = array_merge($groupedErrors['global'], $messages); } } parent::failedValidation($validator); } }