feat: dashboard amélioré, exports budgets, alertes expiration et correctifs
## Dashboard - Refonte complète du tableau de bord avec widgets budgets, commandes, contrats - Intégration des données d'exécution budgétaire en temps réel ## Exports & Rapports - BudgetExecutionExport : export Excel de l'exécution budgétaire - Template PDF budgets (budgets_pdf.blade.php) - Routes d'export PDF et Excel ## Alertes & Notifications - Commande CheckExpirations : détection des contrats/assets arrivant à échéance - Mail ExpiringElementsMail avec template Blade - Planification via routes/console.php ## Correctifs - CommandePolicy et ContratPolicy : ajustements des règles d'autorisation - ContratController : corrections mineures - Commande model : ajustements relations/casts - AuthenticatedLayout : refonte navigation avec icônes budgets - Assets/Form.vue : corrections formulaire - Seeder rôles/permissions mis à jour - Dépendances composer mises à jour (barryvdh/laravel-dompdf, maatwebsite/excel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
89
app/Console/Commands/CheckExpirations.php
Normal file
89
app/Console/Commands/CheckExpirations.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Contrat;
|
||||
use App\Models\Licence;
|
||||
use App\Models\Domaine;
|
||||
use App\Models\User;
|
||||
|
||||
use App\Mail\ExpiringElementsMail;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class CheckExpirations extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:check-expirations';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Vérifie les éléments arrivant à échéance (contrats, licences, garanties) et envoie une notification par email.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$threshold = 30; // jours
|
||||
$today = Carbon::today();
|
||||
$limitDate = Carbon::today()->addDays($threshold);
|
||||
|
||||
// 1. Contrats arrivant à échéance
|
||||
$contrats = Contrat::whereBetween('date_echeance', [$today, $limitDate])
|
||||
->whereNotIn('statut', ['resilie', 'expire'])
|
||||
->get();
|
||||
|
||||
// 2. Licences expirant bientôt
|
||||
$licences = Licence::whereBetween('date_expiration', [$today, $limitDate])
|
||||
->get();
|
||||
|
||||
// 3. Garanties d'assets expirant bientôt
|
||||
$assets = Asset::whereBetween('date_fin_garantie', [$today, $limitDate])
|
||||
->get();
|
||||
|
||||
// 4. Domaines arrivant à échéance
|
||||
$domaines = Domaine::whereBetween('date_echeance', [$today, $limitDate])
|
||||
->get();
|
||||
|
||||
if ($contrats->isEmpty() && $licences->isEmpty() && $assets->isEmpty() && $domaines->isEmpty()) {
|
||||
$this->info('Aucun élément n\'arrive à échéance prochainement.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info(sprintf(
|
||||
'Trouvé : %d contrats, %d licences, %d assets et %d domaines à notifier.',
|
||||
$contrats->count(),
|
||||
$licences->count(),
|
||||
$assets->count(),
|
||||
$domaines->count()
|
||||
));
|
||||
|
||||
|
||||
// Récupérer les administrateurs et responsables
|
||||
$recipients = User::role(['admin', 'responsable'])->get();
|
||||
|
||||
if ($recipients->isEmpty()) {
|
||||
$this->warn('Aucun destinataire (admin ou responsable) trouvé.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
Mail::to($recipient->email)->send(new ExpiringElementsMail($contrats, $licences, $assets, $domaines));
|
||||
}
|
||||
|
||||
|
||||
$this->info('Emails de notification envoyés.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
130
app/Exports/BudgetExecutionExport.php
Normal file
130
app/Exports/BudgetExecutionExport.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\LigneBudget;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
|
||||
class BudgetExecutionExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize, WithTitle
|
||||
{
|
||||
protected $user;
|
||||
protected $annee;
|
||||
protected $filters;
|
||||
|
||||
public function __construct($user, $annee, $filters = [])
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->annee = $annee;
|
||||
$this->filters = $filters;
|
||||
}
|
||||
|
||||
public function title(): string
|
||||
{
|
||||
$parts = ['Exécution Budgétaire', $this->annee];
|
||||
|
||||
if (!empty($this->filters['type'])) {
|
||||
$parts[] = ucfirst($this->filters['type']);
|
||||
}
|
||||
|
||||
if (!empty($this->filters['envelope'])) {
|
||||
$parts[] = ucfirst($this->filters['envelope']);
|
||||
}
|
||||
|
||||
if (!empty($this->filters['service'])) {
|
||||
$parts[] = $this->filters['service'];
|
||||
}
|
||||
|
||||
return substr(implode(' - ', $parts), 0, 31); // Max 31 chars for Excel sheet title
|
||||
}
|
||||
|
||||
public function collection()
|
||||
{
|
||||
$query = LigneBudget::with(['budget.service', 'commandes'])
|
||||
->whereHas('budget', function($q) {
|
||||
$q->where('annee', $this->annee);
|
||||
});
|
||||
|
||||
// Role based access
|
||||
if (!$this->user->hasRole(['admin', 'directeur'])) {
|
||||
$query->whereHas('budget', function($q) {
|
||||
$q->where('service_id', $this->user->service_id);
|
||||
});
|
||||
}
|
||||
|
||||
// Dynamic filters
|
||||
if (!empty($this->filters['type'])) {
|
||||
$query->where('type_depense', $this->filters['type']);
|
||||
}
|
||||
|
||||
if (!empty($this->filters['envelope'])) {
|
||||
$query->whereHas('budget', function($q) {
|
||||
$q->where('type_budget', $this->filters['envelope']);
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($this->filters['service'])) {
|
||||
$query->whereHas('budget.service', function($q) {
|
||||
$q->where('nom', $this->filters['service']);
|
||||
});
|
||||
}
|
||||
|
||||
$statutsConsommes = ['validee', 'commandee', 'partiellement_recue', 'recue_complete', 'cloturee'];
|
||||
$statutsEngages = ['brouillon', 'en_attente_validation'];
|
||||
|
||||
return $query->get()->map(function($lb) use ($statutsConsommes, $statutsEngages) {
|
||||
// Travail en mémoire sur la relation déjà eager-loadée — zéro requête supplémentaire
|
||||
$commandes = $lb->commandes;
|
||||
|
||||
$consomme = (float) $commandes->whereIn('statut', $statutsConsommes)->sum('montant_ttc');
|
||||
$engage = (float) $commandes->whereIn('statut', $statutsEngages)->sum('montant_ttc');
|
||||
|
||||
$lb->consomme = $consomme;
|
||||
$lb->engage = $engage;
|
||||
$lb->total_cumule = $consomme + $engage;
|
||||
$lb->reste = (float) ($lb->montant_arbitre ?? 0) - $lb->total_cumule;
|
||||
$lb->percent = ($lb->montant_arbitre ?? 0) > 0
|
||||
? round(($lb->total_cumule / $lb->montant_arbitre) * 100, 2)
|
||||
: 0;
|
||||
|
||||
return $lb;
|
||||
});
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'ID',
|
||||
'Service',
|
||||
'Type Budget',
|
||||
'Ligne Budgétaire',
|
||||
'Type Dépense',
|
||||
'Enveloppe Arbitrée (€)',
|
||||
'Consommé (€)',
|
||||
'Engagé (€)',
|
||||
'Total Engagé (€)',
|
||||
'Reste (€)',
|
||||
'Taux d\'exécution (%)'
|
||||
];
|
||||
}
|
||||
|
||||
public function map($lb): array
|
||||
{
|
||||
return [
|
||||
$lb->id,
|
||||
$lb->budget->service->nom ?? 'Agglo',
|
||||
$lb->budget->type_budget === 'agglo' ? 'Agglomération' : 'Mutualisé',
|
||||
$lb->nom,
|
||||
$lb->type_depense === 'fonctionnement' ? 'Fonctionnement' : 'Investissement',
|
||||
$lb->montant_arbitre,
|
||||
$lb->consomme,
|
||||
$lb->engage,
|
||||
$lb->total_cumule,
|
||||
$lb->reste,
|
||||
$lb->percent . '%'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class ContratController extends Controller
|
||||
|
||||
$query = Contrat::with(['fournisseur', 'service']);
|
||||
|
||||
if (!$request->user()->hasRole('admin')) {
|
||||
if (!$request->user()->hasAnyRole(['admin', 'raf'])) {
|
||||
$query->where('service_id', $request->user()->service_id);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class ContratController extends Controller
|
||||
->orWhereHas('fournisseur', fn($f) => $f->where('nom', 'like', "%{$search}%"));
|
||||
});
|
||||
})->when($request->service_id, function ($q, $serviceId) use ($request) {
|
||||
if ($request->user()->hasRole('admin')) {
|
||||
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
||||
$q->where('service_id', $serviceId);
|
||||
}
|
||||
})->when($request->fournisseur_id, function ($q, $fournisseurId) {
|
||||
@@ -50,7 +50,7 @@ class ContratController extends Controller
|
||||
|
||||
return Inertia::render('Contrats/Index', [
|
||||
'contrats' => $contrats,
|
||||
'services' => $request->user()->hasRole('admin') ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'services' => $request->user()->hasAnyRole(['admin', 'raf']) ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'fournisseurs' => Fournisseur::active()->orderBy('nom')->get(),
|
||||
'communes' => \App\Models\Commune::orderBy('nom')->get(),
|
||||
'filters' => $request->only(['search', 'service_id', 'fournisseur_id', 'statut']),
|
||||
@@ -63,7 +63,7 @@ class ContratController extends Controller
|
||||
$this->authorize('create', Contrat::class);
|
||||
|
||||
return Inertia::render('Contrats/Create', [
|
||||
'services' => $request->user()->hasRole('admin') ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'services' => $request->user()->hasAnyRole(['admin', 'raf']) ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'fournisseurs' => Fournisseur::active()->orderBy('nom')->get(),
|
||||
'communes' => \App\Models\Commune::orderBy('nom')->get(),
|
||||
'statuts' => Contrat::STATUTS_LABELS,
|
||||
@@ -86,13 +86,13 @@ class ContratController extends Controller
|
||||
];
|
||||
|
||||
// Only admins can select other services, otherwise we force the user's service
|
||||
if ($request->user()->hasRole('admin')) {
|
||||
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
||||
$rules['service_id'] = 'required|exists:services,id';
|
||||
}
|
||||
|
||||
$validated = $request->validate($rules);
|
||||
|
||||
if (!$request->user()->hasRole('admin')) {
|
||||
if (!$request->user()->hasAnyRole(['admin', 'raf'])) {
|
||||
$validated['service_id'] = $request->user()->service_id;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ class ContratController extends Controller
|
||||
|
||||
return Inertia::render('Contrats/Edit', [
|
||||
'contrat' => $contrat,
|
||||
'services' => $request->user()->hasRole('admin') ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'services' => $request->user()->hasAnyRole(['admin', 'raf']) ? Service::all() : Service::where('id', $request->user()->service_id)->get(),
|
||||
'fournisseurs' => Fournisseur::active()->orderBy('nom')->get(),
|
||||
'communes' => \App\Models\Commune::orderBy('nom')->get(),
|
||||
'statuts' => Contrat::STATUTS_LABELS,
|
||||
@@ -142,7 +142,7 @@ class ContratController extends Controller
|
||||
'preavis_jours' => 'nullable|integer|min:0',
|
||||
];
|
||||
|
||||
if ($request->user()->hasRole('admin')) {
|
||||
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
||||
$rules['service_id'] = 'required|exists:services,id';
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ use App\Models\Commande;
|
||||
use App\Models\Service;
|
||||
use App\Models\Contrat;
|
||||
use App\Models\Domaine;
|
||||
use App\Models\Budget;
|
||||
use App\Models\LigneBudget;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
@@ -16,47 +18,61 @@ class DashboardController extends Controller
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$user = $request->user();
|
||||
$isRestricted = !$user->hasRole(['admin', 'directeur', 'raf']);
|
||||
$serviceId = $user->service_id;
|
||||
|
||||
$baseCommande = Commande::query();
|
||||
if ($isRestricted) {
|
||||
$baseCommande->where('service_id', $serviceId);
|
||||
}
|
||||
|
||||
$stats = [
|
||||
'total' => Commande::count(),
|
||||
'en_cours' => Commande::enCours()->count(),
|
||||
'en_retard' => Commande::enRetard()->count(),
|
||||
'brouillons' => Commande::parStatut('brouillon')->count(),
|
||||
'en_attente_validation' => Commande::parStatut('en_attente_validation')->count(),
|
||||
'validees' => Commande::parStatut('validee')->count(),
|
||||
'commandees' => Commande::parStatut('commandee')->count(),
|
||||
'partiellement_recues' => Commande::parStatut('partiellement_recue')->count(),
|
||||
'recues_complete' => Commande::parStatut('recue_complete')->count(),
|
||||
'total' => (clone $baseCommande)->count(),
|
||||
'en_cours' => (clone $baseCommande)->enCours()->count(),
|
||||
'en_retard' => (clone $baseCommande)->enRetard()->count(),
|
||||
'brouillons' => (clone $baseCommande)->parStatut('brouillon')->count(),
|
||||
'en_attente_validation' => (clone $baseCommande)->parStatut('en_attente_validation')->count(),
|
||||
'validees' => (clone $baseCommande)->parStatut('validee')->count(),
|
||||
'commandees' => (clone $baseCommande)->parStatut('commandee')->count(),
|
||||
'partiellement_recues' => (clone $baseCommande)->parStatut('partiellement_recue')->count(),
|
||||
'recues_complete' => (clone $baseCommande)->parStatut('recue_complete')->count(),
|
||||
];
|
||||
|
||||
$commandesRecentes = Commande::with(['service', 'fournisseur', 'demandeur'])
|
||||
$commandesRecentes = (clone $baseCommande)->with(['service', 'fournisseur', 'demandeur'])
|
||||
->latest()
|
||||
->limit(8)
|
||||
->get();
|
||||
|
||||
$commandesEnRetard = Commande::enRetard()
|
||||
$commandesEnRetard = (clone $baseCommande)->enRetard()
|
||||
->with(['service', 'fournisseur', 'demandeur'])
|
||||
->orderBy('date_souhaitee')
|
||||
->limit(10)
|
||||
->get();
|
||||
|
||||
$commandesUrgentes = Commande::urgentes()
|
||||
$commandesUrgentes = (clone $baseCommande)->urgentes()
|
||||
->enCours()
|
||||
->with(['service', 'fournisseur', 'demandeur'])
|
||||
->latest()
|
||||
->limit(5)
|
||||
->get();
|
||||
|
||||
$statsParStatut = Commande::select('statut', DB::raw('count(*) as total'))
|
||||
$statsParStatut = (clone $baseCommande)->select('statut', DB::raw('count(*) as total'))
|
||||
->groupBy('statut')
|
||||
->get()
|
||||
->keyBy('statut');
|
||||
|
||||
$statsParService = Service::withCount([
|
||||
$statsParServiceQuery = Service::withCount([
|
||||
'commandes',
|
||||
'commandes as commandes_en_cours_count' => fn ($q) => $q->enCours(),
|
||||
])->get();
|
||||
]);
|
||||
|
||||
if ($isRestricted) {
|
||||
$statsParServiceQuery->where('id', $serviceId);
|
||||
}
|
||||
|
||||
$statsParService = $statsParServiceQuery->get();
|
||||
|
||||
$montantParMois = Commande::select(
|
||||
$montantParMois = (clone $baseCommande)->select(
|
||||
DB::raw('YEAR(date_demande) as annee'),
|
||||
DB::raw('MONTH(date_demande) as mois'),
|
||||
DB::raw('SUM(montant_ttc) as total_ttc'),
|
||||
@@ -70,7 +86,7 @@ class DashboardController extends Controller
|
||||
|
||||
// Stats Contrats
|
||||
$contratsQuery = Contrat::query();
|
||||
if (!$user->hasRole('admin')) {
|
||||
if (!$user->hasRole(['admin', 'raf'])) {
|
||||
$contratsQuery->where('service_id', $user->service_id);
|
||||
}
|
||||
$tousContrats = $contratsQuery->get();
|
||||
@@ -88,6 +104,40 @@ class DashboardController extends Controller
|
||||
'en_retard' => $tousDomaines->filter(fn($d) => $d->est_en_retard)->count(),
|
||||
];
|
||||
|
||||
// Stats Budget
|
||||
$anneeCourante = now()->year;
|
||||
|
||||
$budgetQuery = LigneBudget::whereHas('budget', function($q) use ($anneeCourante) {
|
||||
$q->where('annee', $anneeCourante);
|
||||
});
|
||||
|
||||
if ($isRestricted) {
|
||||
$budgetQuery->whereHas('budget', function($q) use ($serviceId) {
|
||||
$q->where('service_id', $serviceId);
|
||||
});
|
||||
}
|
||||
|
||||
$budgetsStats = [];
|
||||
foreach (['agglo', 'mutualise'] as $typeBudget) {
|
||||
$budgetQueryType = (clone $budgetQuery)->whereHas('budget', fn($q) => $q->where('type_budget', $typeBudget));
|
||||
$baseCommandeType = (clone $baseCommande)->whereHas('ligneBudget.budget', function($q) use ($anneeCourante, $typeBudget) {
|
||||
$q->where('annee', $anneeCourante)->where('type_budget', $typeBudget);
|
||||
})->whereNotIn('statut', ['annulee']);
|
||||
|
||||
$budgetsStats[$typeBudget] = [
|
||||
'total_arbitre' => $budgetQueryType->sum('montant_arbitre'),
|
||||
'consomme' => $baseCommandeType->sum('montant_ttc'),
|
||||
'fonctionnement' => [
|
||||
'total_arbitre' => (clone $budgetQueryType)->where('type_depense', 'fonctionnement')->sum('montant_arbitre'),
|
||||
'consomme' => (clone $baseCommandeType)->whereHas('ligneBudget', fn($q) => $q->where('type_depense', 'fonctionnement'))->sum('montant_ttc'),
|
||||
],
|
||||
'investissement' => [
|
||||
'total_arbitre' => (clone $budgetQueryType)->where('type_depense', 'investissement')->sum('montant_arbitre'),
|
||||
'consomme' => (clone $baseCommandeType)->whereHas('ligneBudget', fn($q) => $q->where('type_depense', 'investissement'))->sum('montant_ttc'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return Inertia::render('Dashboard/Index', compact(
|
||||
'stats',
|
||||
'commandesRecentes',
|
||||
@@ -98,6 +148,7 @@ class DashboardController extends Controller
|
||||
'montantParMois',
|
||||
'statsContrats',
|
||||
'statsDomaines',
|
||||
'budgetsStats',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
56
app/Mail/ExpiringElementsMail.php
Normal file
56
app/Mail/ExpiringElementsMail.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ExpiringElementsMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public Collection $contrats,
|
||||
public Collection $licences,
|
||||
public Collection $assets,
|
||||
public Collection $domaines
|
||||
) {}
|
||||
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
subject: '[DSICommander] Alerte : Éléments arrivant à échéance prochainement',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*/
|
||||
public function content(): Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'emails.expiring_elements',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments for the message.
|
||||
*
|
||||
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
|
||||
*/
|
||||
public function attachments(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ class Commande extends Model
|
||||
protected $fillable = [
|
||||
'numero_commande', 'service_id', 'fournisseur_id', 'user_id', 'commune_id',
|
||||
'validateur_id', 'acheteur_id', 'objet', 'description', 'justification',
|
||||
'statut', 'priorite', 'reference_fournisseur', 'imputation_budgetaire',
|
||||
'statut', 'priorite', 'reference_fournisseur', 'imputation_budgetaire', 'ligne_budget_id',
|
||||
'montant_ht', 'montant_ttc',
|
||||
'date_demande', 'date_souhaitee', 'date_validation', 'date_commande',
|
||||
'date_livraison_prevue', 'date_reception', 'date_reception_complete', 'date_cloture',
|
||||
@@ -133,6 +133,11 @@ class Commande extends Model
|
||||
return $this->hasMany(PieceJointe::class)->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function ligneBudget(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(LigneBudget::class, 'ligne_budget_id');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Scopes
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@@ -19,12 +19,12 @@ class CommandePolicy
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->hasAnyRole(['admin', 'responsable', 'acheteur']);
|
||||
return $user->hasAnyRole(['admin', 'responsable', 'acheteur', 'raf']);
|
||||
}
|
||||
|
||||
public function update(User $user, Commande $commande): bool
|
||||
{
|
||||
if ($user->hasRole('admin')) {
|
||||
if ($user->hasAnyRole(['admin', 'raf'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class CommandePolicy
|
||||
|
||||
public function delete(User $user, Commande $commande): bool
|
||||
{
|
||||
return $user->hasRole('admin');
|
||||
return $user->hasAnyRole(['admin', 'raf']);
|
||||
}
|
||||
|
||||
public function transition(User $user, Commande $commande, string $targetStatut): bool
|
||||
@@ -48,7 +48,7 @@ class CommandePolicy
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user->hasRole('admin')) {
|
||||
if ($user->hasAnyRole(['admin', 'raf'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class ContratPolicy
|
||||
|
||||
public function view(User $user, Contrat $contrat): bool
|
||||
{
|
||||
if ($user->hasRole('admin')) {
|
||||
if ($user->hasAnyRole(['admin', 'raf'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class ContratPolicy
|
||||
|
||||
public function update(User $user, Contrat $contrat): bool
|
||||
{
|
||||
if ($user->hasRole('admin')) {
|
||||
if ($user->hasAnyRole(['admin', 'raf'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class ContratPolicy
|
||||
|
||||
public function delete(User $user, Contrat $contrat): bool
|
||||
{
|
||||
if ($user->hasRole('admin')) {
|
||||
if ($user->hasAnyRole(['admin', 'raf'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user