## 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>
167 lines
6.2 KiB
PHP
167 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Contrat;
|
|
use App\Models\Fournisseur;
|
|
use App\Models\Service;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ContratController extends Controller
|
|
{
|
|
public function index(Request $request): Response
|
|
{
|
|
$this->authorize('viewAny', Contrat::class);
|
|
|
|
$query = Contrat::with(['fournisseur', 'service']);
|
|
|
|
if (!$request->user()->hasAnyRole(['admin', 'raf'])) {
|
|
$query->where('service_id', $request->user()->service_id);
|
|
}
|
|
|
|
$query->when($request->search, function ($q, $search) {
|
|
$q->where(function ($sub) use ($search) {
|
|
$sub->where('titre', 'like', "%{$search}%")
|
|
->orWhereHas('fournisseur', fn($f) => $f->where('nom', 'like', "%{$search}%"));
|
|
});
|
|
})->when($request->service_id, function ($q, $serviceId) use ($request) {
|
|
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
|
$q->where('service_id', $serviceId);
|
|
}
|
|
})->when($request->fournisseur_id, function ($q, $fournisseurId) {
|
|
$q->where('fournisseur_id', $fournisseurId);
|
|
})->when($request->commune_id, function ($q, $communeId) {
|
|
$q->where('commune_id', $communeId);
|
|
})->when($request->statut, function ($q, $statut) {
|
|
$q->where('statut', $statut);
|
|
});
|
|
|
|
$contrats = $query->orderBy('date_echeance', 'asc')->paginate(20)->withQueryString();
|
|
|
|
// Calculate estProcheEcheance for the frontend
|
|
$contrats->getCollection()->transform(function ($contrat) {
|
|
$contrat->append(['est_proche_echeance', 'est_en_retard']);
|
|
return $contrat;
|
|
});
|
|
|
|
return Inertia::render('Contrats/Index', [
|
|
'contrats' => $contrats,
|
|
'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']),
|
|
'statuts' => Contrat::STATUTS_LABELS,
|
|
]);
|
|
}
|
|
|
|
public function create(Request $request): Response
|
|
{
|
|
$this->authorize('create', Contrat::class);
|
|
|
|
return Inertia::render('Contrats/Create', [
|
|
'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,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
$this->authorize('create', Contrat::class);
|
|
|
|
$rules = [
|
|
'titre' => 'required|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'fournisseur_id' => 'required|exists:fournisseurs,id',
|
|
'date_debut' => 'nullable|date',
|
|
'date_echeance' => 'required|date',
|
|
'statut' => 'required|in:actif,a_renouveler,expire,resilie',
|
|
'montant' => 'nullable|numeric|min:0',
|
|
'preavis_jours' => 'nullable|integer|min:0',
|
|
];
|
|
|
|
// Only admins can select other services, otherwise we force the user's service
|
|
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
|
$rules['service_id'] = 'required|exists:services,id';
|
|
}
|
|
|
|
$validated = $request->validate($rules);
|
|
|
|
if (!$request->user()->hasAnyRole(['admin', 'raf'])) {
|
|
$validated['service_id'] = $request->user()->service_id;
|
|
}
|
|
|
|
$contrat = Contrat::create($validated);
|
|
|
|
return redirect()->route('contrats.index')
|
|
->with('success', 'Contrat créé avec succès.');
|
|
}
|
|
|
|
public function show(Contrat $contrat): Response
|
|
{
|
|
$this->authorize('view', $contrat);
|
|
|
|
$contrat->load(['fournisseur', 'service', 'commune', 'piecesJointes.user']);
|
|
$contrat->append(['est_proche_echeance', 'est_en_retard']);
|
|
|
|
return Inertia::render('Contrats/Show', [
|
|
'contrat' => $contrat,
|
|
]);
|
|
}
|
|
|
|
public function edit(Contrat $contrat, Request $request): Response
|
|
{
|
|
$this->authorize('update', $contrat);
|
|
|
|
return Inertia::render('Contrats/Edit', [
|
|
'contrat' => $contrat,
|
|
'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,
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, Contrat $contrat): RedirectResponse
|
|
{
|
|
$this->authorize('update', $contrat);
|
|
|
|
$rules = [
|
|
'titre' => 'required|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'fournisseur_id' => 'required|exists:fournisseurs,id',
|
|
'date_debut' => 'nullable|date',
|
|
'date_echeance' => 'required|date',
|
|
'statut' => 'required|in:actif,a_renouveler,expire,resilie',
|
|
'montant' => 'nullable|numeric|min:0',
|
|
'preavis_jours' => 'nullable|integer|min:0',
|
|
];
|
|
|
|
if ($request->user()->hasAnyRole(['admin', 'raf'])) {
|
|
$rules['service_id'] = 'required|exists:services,id';
|
|
}
|
|
|
|
$validated = $request->validate($rules);
|
|
|
|
$contrat->update($validated);
|
|
|
|
return redirect()->route('contrats.show', $contrat)
|
|
->with('success', 'Contrat mis à jour.');
|
|
}
|
|
|
|
public function destroy(Contrat $contrat): RedirectResponse
|
|
{
|
|
$this->authorize('delete', $contrat);
|
|
|
|
$contrat->delete();
|
|
|
|
return redirect()->route('contrats.index')
|
|
->with('success', 'Contrat supprimé.');
|
|
}
|
|
}
|