- Devis: CRUD complet, génération PDF (dompdf), paramètres (DevisSetting) - BesoinInformatique: CRUD complet avec gestion matériels/licences - Migrations pour les 3 nouvelles tables - Navigation mise à jour dans AuthenticatedLayout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
178 lines
5.7 KiB
PHP
178 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Devis;
|
|
use App\Models\DevisSetting;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Barryvdh\DomPDF\Facade\Pdf;
|
|
|
|
class DevisController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$devis = Devis::latest()->get();
|
|
return Inertia::render('Devis/Index', [
|
|
'devis' => $devis
|
|
]);
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
return Inertia::render('Devis/Create');
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'title' => 'required|string|max:255',
|
|
'destinataire_type' => 'required|string|in:commune,service_interne',
|
|
'destinataire_nom' => 'required|string|max:255',
|
|
'referent' => 'nullable|string|max:255',
|
|
'date_devis' => 'required|date',
|
|
'status' => 'required|string|in:draft,sent,accepted,rejected',
|
|
'items' => 'nullable|array',
|
|
'tva_rate' => 'nullable|numeric|min:0|max:100',
|
|
'notes' => 'nullable|string',
|
|
]);
|
|
|
|
// Calculer les montants
|
|
$totalHt = 0;
|
|
if (!empty($validated['items'])) {
|
|
foreach ($validated['items'] as $item) {
|
|
$qty = floatval($item['quantite'] ?? 0);
|
|
$price = floatval($item['prix_unitaire'] ?? 0);
|
|
$totalHt += $qty * $price;
|
|
}
|
|
}
|
|
|
|
$tvaRate = floatval($validated['tva_rate'] ?? 20);
|
|
$totalTtc = $totalHt * (1 + ($tvaRate / 100));
|
|
|
|
$validated['total_ht'] = $totalHt;
|
|
$validated['total_ttc'] = $totalTtc;
|
|
|
|
Devis::create($validated);
|
|
|
|
return redirect()->route('devis.index')->with('success', 'Devis créé avec succès.');
|
|
}
|
|
|
|
public function show(Devis $devi)
|
|
{
|
|
$settings = DevisSetting::first() ?? DevisSetting::create([
|
|
'entity_name' => "Direction des Systèmes d'Information",
|
|
'entity_sub' => "Communauté d'Agglomération Béziers Méditerranée",
|
|
'email' => "support.informatique@beziers-mediterranee.fr",
|
|
'telephone' => "04.67.01.60.00",
|
|
'adresse' => "Béziers, France",
|
|
]);
|
|
|
|
return Inertia::render('Devis/Show', [
|
|
'devis' => $devi,
|
|
'settings' => $settings
|
|
]);
|
|
}
|
|
|
|
public function edit(Devis $devi)
|
|
{
|
|
return Inertia::render('Devis/Edit', [
|
|
'devis' => $devi
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, Devis $devi)
|
|
{
|
|
$validated = $request->validate([
|
|
'title' => 'required|string|max:255',
|
|
'destinataire_type' => 'required|string|in:commune,service_interne',
|
|
'destinataire_nom' => 'required|string|max:255',
|
|
'referent' => 'nullable|string|max:255',
|
|
'date_devis' => 'required|date',
|
|
'status' => 'required|string|in:draft,sent,accepted,rejected',
|
|
'items' => 'nullable|array',
|
|
'tva_rate' => 'nullable|numeric|min:0|max:100',
|
|
'notes' => 'nullable|string',
|
|
]);
|
|
|
|
// Calculer les montants
|
|
$totalHt = 0;
|
|
if (!empty($validated['items'])) {
|
|
foreach ($validated['items'] as $item) {
|
|
$qty = floatval($item['quantite'] ?? 0);
|
|
$price = floatval($item['prix_unitaire'] ?? 0);
|
|
$totalHt += $qty * $price;
|
|
}
|
|
}
|
|
|
|
$tvaRate = floatval($validated['tva_rate'] ?? 20);
|
|
$totalTtc = $totalHt * (1 + ($tvaRate / 100));
|
|
|
|
$validated['total_ht'] = $totalHt;
|
|
$validated['total_ttc'] = $totalTtc;
|
|
|
|
$devi->update($validated);
|
|
|
|
return redirect()->route('devis.index')->with('success', 'Devis mis à jour avec succès.');
|
|
}
|
|
|
|
public function destroy(Devis $devi)
|
|
{
|
|
$devi->delete();
|
|
return redirect()->route('devis.index')->with('success', 'Devis supprimé avec succès.');
|
|
}
|
|
|
|
public function settings()
|
|
{
|
|
$settings = DevisSetting::first() ?? DevisSetting::create([
|
|
'entity_name' => "Direction des Systèmes d'Information",
|
|
'entity_sub' => "Communauté d'Agglomération Béziers Méditerranée",
|
|
'email' => "support.informatique@beziers-mediterranee.fr",
|
|
'telephone' => "04.67.01.60.00",
|
|
'adresse' => "Béziers, France",
|
|
]);
|
|
|
|
return Inertia::render('Devis/Settings', [
|
|
'settings' => $settings
|
|
]);
|
|
}
|
|
|
|
public function updateSettings(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'entity_name' => 'required|string|max:255',
|
|
'entity_sub' => 'required|string|max:255',
|
|
'email' => 'required|email|max:255',
|
|
'telephone' => 'required|string|max:50',
|
|
'adresse' => 'nullable|string|max:255',
|
|
]);
|
|
|
|
$settings = DevisSetting::first();
|
|
if ($settings) {
|
|
$settings->update($validated);
|
|
} else {
|
|
DevisSetting::create($validated);
|
|
}
|
|
|
|
return redirect()->route('devis.index')->with('success', 'Paramètres du devis mis à jour avec succès.');
|
|
}
|
|
|
|
public function downloadPdf(Devis $devi)
|
|
{
|
|
$settings = DevisSetting::first() ?? DevisSetting::create([
|
|
'entity_name' => "Direction des Systèmes d'Information",
|
|
'entity_sub' => "Communauté d'Agglomération Béziers Méditerranée",
|
|
'email' => "support.informatique@beziers-mediterranee.fr",
|
|
'telephone' => "04.67.01.60.00",
|
|
'adresse' => "Béziers, France",
|
|
]);
|
|
|
|
$pdf = Pdf::loadView('pdf.devis', [
|
|
'devis' => $devi,
|
|
'settings' => $settings,
|
|
]);
|
|
|
|
return $pdf->download("devis-{$devi->number}.pdf");
|
|
}
|
|
}
|