270 lines
9.2 KiB
PHP
270 lines
9.2 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::with(['sousDevis', 'parent'])->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",
|
|
]);
|
|
|
|
$devi->load(['sousDevis', 'parent']);
|
|
|
|
return Inertia::render('Devis/Show', [
|
|
'devis' => $devi,
|
|
'settings' => $settings,
|
|
]);
|
|
}
|
|
|
|
public function createFromCommande(\App\Models\Order $commande)
|
|
{
|
|
$commande->load('attachments');
|
|
$quoteAttachments = $commande->attachments->where('file_type', 'quote')->map(fn($a) => [
|
|
'id' => $a->id,
|
|
'file_name' => $a->file_name,
|
|
])->values()->all();
|
|
|
|
return Inertia::render('Devis/CreateFromCommande', [
|
|
'commande' => [
|
|
'id' => $commande->id,
|
|
'number' => $commande->number,
|
|
'label' => $commande->label,
|
|
'supplier' => $commande->supplier,
|
|
'quote_number' => $commande->quote_number,
|
|
'quote_attachments' => $quoteAttachments,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function storeFromCommande(Request $request, \App\Models\Order $commande)
|
|
{
|
|
$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' => 'required|array|min:1',
|
|
'tva_rate' => 'nullable|numeric|min:0|max:100',
|
|
'notes' => 'nullable|string',
|
|
]);
|
|
|
|
$totalHt = 0;
|
|
foreach ($validated['items'] as $item) {
|
|
$totalHt += floatval($item['quantite'] ?? 0) * floatval($item['prix_unitaire'] ?? 0);
|
|
}
|
|
|
|
$tvaRate = floatval($validated['tva_rate'] ?? 20);
|
|
|
|
$validated['total_ht'] = $totalHt;
|
|
$validated['total_ttc'] = $totalHt * (1 + ($tvaRate / 100));
|
|
$validated['commande_id'] = $commande->id;
|
|
$validated['commande_number'] = $commande->number;
|
|
|
|
Devis::create($validated);
|
|
|
|
return redirect()->route('commandes.show', $commande->id)
|
|
->with('success', 'Sous-devis créé avec succès.');
|
|
}
|
|
|
|
public function createSousDevis(Devis $devi)
|
|
{
|
|
return Inertia::render('Devis/CreateSousDevis', [
|
|
'parentDevis' => $devi,
|
|
]);
|
|
}
|
|
|
|
public function storeSousDevis(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' => 'required|array|min:1',
|
|
'tva_rate' => 'nullable|numeric|min:0|max:100',
|
|
'notes' => 'nullable|string',
|
|
]);
|
|
|
|
$totalHt = 0;
|
|
foreach ($validated['items'] as $item) {
|
|
$totalHt += floatval($item['quantite'] ?? 0) * floatval($item['prix_unitaire'] ?? 0);
|
|
}
|
|
|
|
$tvaRate = floatval($validated['tva_rate'] ?? 20);
|
|
|
|
$validated['total_ht'] = $totalHt;
|
|
$validated['total_ttc'] = $totalHt * (1 + ($tvaRate / 100));
|
|
$validated['parent_devis_id'] = $devi->id;
|
|
|
|
Devis::create($validated);
|
|
|
|
return redirect()->route('devis.show', $devi->id)
|
|
->with('success', 'Sous-devis créé avec succès.');
|
|
}
|
|
|
|
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");
|
|
}
|
|
}
|