Allow invoices to target either a client or a client group by making `client_id` nullable and validating that exactly one recipient is set. Load group relations in invoice data so the frontend can display group details in invoice views and type definitions. Make quote acceptance reuse an existing invoice instead of creating a duplicate, and surface backend status update errors in the quote UI.
94 lines
3.9 KiB
PHP
94 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Requests;
|
|
|
|
use Illuminate\Foundation\Http\FormRequest;
|
|
|
|
class UpdateInvoiceRequest extends FormRequest
|
|
{
|
|
/**
|
|
* Determine if the user is authorized to make this request.
|
|
*/
|
|
public function authorize(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get the validation rules that apply to the request.
|
|
*
|
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
|
*/
|
|
public function rules(): array
|
|
{
|
|
$invoiceId = $this->route('invoice');
|
|
|
|
return [
|
|
'client_id' => 'nullable|exists:clients,id',
|
|
'group_id' => 'nullable|exists:client_groups,id',
|
|
'source_quote_id' => 'nullable|exists:quotes,id',
|
|
'invoice_number' => 'sometimes|string|max:191|unique:invoices,invoice_number,' . $invoiceId,
|
|
'status' => 'sometimes|in:brouillon,emise,envoyee,partiellement_payee,payee,echue,annulee,avoir',
|
|
'invoice_date' => 'sometimes|date',
|
|
'due_date' => 'nullable|date|after_or_equal:invoice_date',
|
|
'currency' => 'sometimes|string|size:3',
|
|
'total_ht' => 'sometimes|numeric|min:0',
|
|
'total_tva' => 'sometimes|numeric|min:0',
|
|
'total_ttc' => 'sometimes|numeric|min:0',
|
|
'e_invoicing_channel_id' => 'nullable|exists:e_invoicing_channels,id',
|
|
'e_invoice_status' => 'nullable|in:cree,transmis,accepte,refuse,en_litige,acquitte,archive',
|
|
];
|
|
}
|
|
|
|
public function messages(): array
|
|
{
|
|
return [
|
|
'client_id.exists' => 'Le client sélectionné est invalide.',
|
|
'group_id.exists' => 'Le groupe sélectionné est invalide.',
|
|
'source_quote_id.exists' => 'Le devis source est invalide.',
|
|
'invoice_number.string' => 'Le numéro de facture doit être une chaîne de caractères.',
|
|
'invoice_number.max' => 'Le numéro de facture ne doit pas dépasser 191 caractères.',
|
|
'invoice_number.unique' => 'Ce numéro de facture existe déjà.',
|
|
'status.in' => 'Le statut sélectionné est invalide.',
|
|
'invoice_date.date' => 'La date de la facture n\'est pas valide.',
|
|
'due_date.date' => 'La date d\'échéance n\'est pas valide.',
|
|
'due_date.after_or_equal' => 'La date d\'échéance doit être postérieure ou égale à la date de la facture.',
|
|
'currency.size' => 'La devise doit comporter 3 caractères.',
|
|
'total_ht.numeric' => 'Le total HT doit être un nombre.',
|
|
'total_ht.min' => 'Le total HT ne peut pas être négatif.',
|
|
'total_tva.numeric' => 'Le total TVA doit être un nombre.',
|
|
'total_tva.min' => 'Le total TVA ne peut pas être négatif.',
|
|
'total_ttc.numeric' => 'Le total TTC doit être un nombre.',
|
|
'total_ttc.min' => 'Le total TTC ne peut pas être négatif.',
|
|
'e_invoicing_channel_id.exists' => 'Le canal de facturation électronique est invalide.',
|
|
'e_invoice_status.in' => 'Le statut de facturation électronique est invalide.',
|
|
];
|
|
}
|
|
|
|
public function withValidator($validator): void
|
|
{
|
|
$validator->after(function ($validator) {
|
|
if (! $this->hasAny(['client_id', 'group_id'])) {
|
|
return;
|
|
}
|
|
|
|
$hasClient = filled($this->input('client_id'));
|
|
$hasGroup = filled($this->input('group_id'));
|
|
|
|
if (! $hasClient && ! $hasGroup) {
|
|
$message = 'Un client ou un groupe de clients est obligatoire.';
|
|
|
|
$validator->errors()->add('client_id', $message);
|
|
$validator->errors()->add('group_id', $message);
|
|
}
|
|
|
|
if ($hasClient && $hasGroup) {
|
|
$message = 'Selectionnez soit un client, soit un groupe de clients.';
|
|
|
|
$validator->errors()->add('client_id', $message);
|
|
$validator->errors()->add('group_id', $message);
|
|
}
|
|
});
|
|
}
|
|
}
|