kevin 284d228dc5 feat(vehicle): add vehicle+convoy feature with API, models, repos, UI
Adds model, repo, controller, and request classes for Vehicle and Convoy.
Registers routes for vehicles and convoys, updates client store.
Adds front‑end files to list, add, edit vehicles.
Cleans up console logging from client store.
2026-04-15 17:27:40 +03:00

113 lines
2.6 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Client extends Model
{
use HasFactory;
protected $fillable = [
'name',
'vat_number',
'siret',
'email',
'phone',
'billing_address_line1',
'billing_address_line2',
'billing_postal_code',
'billing_city',
'billing_country_code',
'group_id',
'notes',
'is_active',
'is_parent',
'parent_id',
// 'default_tva_rate_id',
'client_category_id',
'user_id',
'avatar',
];
protected $casts = [
'is_active' => 'boolean',
'is_parent' => 'boolean',
];
public function parent(): BelongsTo
{
return $this->belongsTo(Client::class, 'parent_id');
}
public function children()
{
return $this->hasMany(Client::class, 'parent_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function commercial(): ?string
{
return $this->user ? $this->user->name : 'Système';
}
public function category(): BelongsTo
{
return $this->belongsTo(ClientCategory::class, 'client_category_id');
}
public function group(): BelongsTo
{
return $this->belongsTo(ClientGroup::class, 'group_id');
}
public function convoys()
{
return $this->hasMany(Convoy::class);
}
/**
* Get the human-readable label for the client type.
*/
public function getTypeLabel(): string
{
return $this->category ? $this->category->name : 'Non catégorisé';
}
/**
* Get the full billing address as a string.
*/
public function getBillingAddressAttribute(): ?string
{
$parts = array_filter([
$this->billing_address_line1,
$this->billing_address_line2,
$this->billing_postal_code ? $this->billing_postal_code . ' ' . $this->billing_city : $this->billing_city,
$this->billing_country_code,
]);
return !empty($parts) ? implode(', ', $parts) : null;
}
/**
* Get the file attachments for the client (polymorphic).
*/
public function fileAttachments()
{
return $this->morphMany(FileAttachment::class, 'attachable')->orderBy('sort_order');
}
/**
* Get the files attached to this client.
*/
public function attachedFiles()
{
return $this->fileAttachments()->with('file');
}
}