Initial commit: Import existing Laravel project

This commit is contained in:
jeremy bayse
2026-06-15 08:12:33 +02:00
parent 7420d1b466
commit 030d76af53
143 changed files with 21885 additions and 1 deletions

35
app/Models/Attachment.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Attachment extends Model
{
protected $fillable = [
'order_id',
'file_path',
'file_name',
'file_type',
];
protected $appends = ['url'];
/**
* Relation avec la commande.
*/
public function order()
{
return $this->belongsTo(Order::class);
}
/**
* Accesseur pour obtenir l'URL de téléchargement sécurisée.
*/
public function getUrlAttribute()
{
return route('attachments.show', $this->id);
}
}

123
app/Models/Hardware.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class Hardware extends Model
{
protected $table = 'hardwares';
protected $fillable = [
'name',
'type',
'brand',
'model',
'serial_number',
'status',
'purchase_date',
'commissioning_date',
'warranty_expiration_date',
'location',
'ip_address',
'order_id',
'notes',
];
protected $casts = [
'purchase_date' => 'date',
'commissioning_date' => 'date',
'warranty_expiration_date' => 'date',
];
protected $appends = [
'is_under_warranty',
'warranty_status_label',
'warranty_remaining_days',
];
/**
* Relation avec la commande d'achat.
*/
public function order()
{
return $this->belongsTo(Order::class);
}
/**
* Accesseur : l'équipement est-il sous garantie ?
*/
public function getIsUnderWarrantyAttribute(): bool
{
if (!$this->warranty_expiration_date) {
return false;
}
return $this->warranty_expiration_date->isAfter(Carbon::today());
}
/**
* Accesseur : label en français du statut de garantie.
*/
public function getWarrantyStatusLabelAttribute(): string
{
if (!$this->warranty_expiration_date) {
return 'Non spécifiée';
}
if ($this->is_under_warranty) {
$days = $this->warranty_remaining_days;
return "Sous garantie ($days j. restants)";
}
return 'Garantie expirée';
}
/**
* Accesseur : nombre de jours de garantie restants.
*/
public function getWarrantyRemainingDaysAttribute(): ?int
{
if (!$this->warranty_expiration_date) {
return null;
}
if ($this->warranty_expiration_date->isBefore(Carbon::today())) {
return 0;
}
return (int) Carbon::today()->diffInDays($this->warranty_expiration_date);
}
/**
* Scope : Moteur de recherche multicritère
*/
public function scopeSearch($query, $search)
{
return $query->where(function ($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('brand', 'like', "%{$search}%")
->orWhere('model', 'like', "%{$search}%")
->orWhere('serial_number', 'like', "%{$search}%")
->orWhere('location', 'like', "%{$search}%")
->orWhere('ip_address', 'like', "%{$search}%");
});
}
/**
* Scope : Filtrer par type
*/
public function scopeByType($query, $type)
{
return $query->where('type', $type);
}
/**
* Scope : Filtrer par statut
*/
public function scopeByStatus($query, $status)
{
return $query->where('status', $status);
}
}

84
app/Models/Order.php Normal file
View File

@@ -0,0 +1,84 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $fillable = [
'number',
'label',
'type',
'supplier',
'quote_number',
'amount_ht',
'amount_ttc',
'exclude_vat',
'requested_by',
'prescriber',
'delivery_deadline',
'status',
'notes',
];
protected $casts = [
'delivery_deadline' => 'date',
'amount_ht' => 'decimal:2',
'amount_ttc' => 'decimal:2',
'exclude_vat' => 'boolean',
];
/**
* Relation avec l'historique des changements de statut.
*/
public function statusLogs()
{
return $this->hasMany(OrderStatusLog::class)->orderBy('changed_at', 'desc');
}
/**
* Relation avec les pièces jointes.
*/
public function attachments()
{
return $this->hasMany(Attachment::class);
}
/**
* Scope par statut(s).
*/
public function scopeByStatus($query, $status)
{
if (empty($status)) {
return $query;
}
if (is_array($status)) {
return $query->whereIn('status', $status);
}
return $query->where('status', $status);
}
/**
* Scope par demandeur(s).
*/
public function scopeByDemandeur($query, $demandeur)
{
if (empty($demandeur)) {
return $query;
}
if (is_array($demandeur)) {
return $query->whereIn('requested_by', $demandeur);
}
return $query->where('requested_by', $demandeur);
}
/**
* Scope pour les commandes en retard de livraison (date dépassée et non livrée/clôturée).
*/
public function scopeOverdue($query)
{
return $query->where('delivery_deadline', '<', now()->toDateString())
->whereNotIn('status', ['delivered', 'closed']);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OrderStatusLog extends Model
{
public $timestamps = false;
protected $fillable = [
'order_id',
'user_id',
'old_status',
'new_status',
'changed_at',
];
protected $casts = [
'changed_at' => 'datetime',
];
/**
* Relation avec la commande.
*/
public function order()
{
return $this->belongsTo(Order::class);
}
/**
* Relation avec l'utilisateur qui a fait la transition.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}

48
app/Models/User.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
#[Fillable(['name', 'email', 'password', 'role'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
/**
* Vérifie si l'utilisateur est le Chef de Service.
*/
public function isChefService(): bool
{
return $this->role === 'chef_service';
}
/**
* Vérifie si l'utilisateur est un Administrateur Réseau.
*/
public function isAdminReseau(): bool
{
return $this->role === 'admin_reseau';
}
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}