feat: add sous-devis generation from commandes

From a commande, users can now create one or more sub-quotes
(sous-devis) to ventilate purchases across communes for approval.

- Add parent_devis_id and commande_id FKs on devis table
- Order model: sousDevis() hasMany relation
- Devis model: commande() and parent() relations
- DevisController: createFromCommande / storeFromCommande methods
- OrderController: load and pass sous_devis on show
- Commandes/Show: "Créer un sous-devis" button + ventilation panel
- Devis/CreateFromCommande: form pre-loaded with commande context
- Devis/Index: badge "Sous-devis · CMD-XXXX" on linked quotes
- Devis/Show: back-link to originating commande

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mrKamoo
2026-06-19 15:14:45 +02:00
co-authored by Claude Sonnet 4.6
parent 7312c7640b
commit 8d51f4de3e
12 changed files with 874 additions and 15 deletions
+15 -4
View File
@@ -1,11 +1,14 @@
<script setup>
import { computed } from 'vue';
import { Head, Link } from '@inertiajs/vue3';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
defineProps({
const props = defineProps({
devis: Array,
});
const orderedDevis = computed(() => props.devis);
const getStatusClasses = (status) => {
switch (status) {
case 'draft':
@@ -96,15 +99,23 @@ const formatCurrency = (value) => {
</thead>
<tbody class="divide-y divide-slate-100 dark:divide-slate-850 text-sm">
<tr
v-for="d in devis"
v-for="d in orderedDevis"
:key="d.id"
class="hover:bg-slate-50/50 dark:hover:bg-slate-950/20 transition-colors"
:class="[
'hover:bg-slate-50/50 dark:hover:bg-slate-950/20 transition-colors',
!d._isParent ? 'bg-violet-50/30 dark:bg-violet-950/10' : ''
]"
>
<!-- Numéro -->
<td class="px-6 py-4 font-mono text-xs font-bold text-sky-600 dark:text-sky-400">
<Link :href="route('devis.show', d.id)" class="hover:underline">
{{ d.number }}
</Link>
<div v-if="d.commande_id" class="mt-0.5">
<span class="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xxs font-bold bg-violet-100 text-violet-700 dark:bg-violet-950/40 dark:text-violet-300 border border-violet-200 dark:border-violet-900/60">
Sous-devis · {{ d.commande_number }}
</span>
</div>
</td>
<!-- Objet -->
<td class="px-6 py-4 font-medium text-slate-800 dark:text-slate-200">
@@ -169,7 +180,7 @@ const formatCurrency = (value) => {
</div>
</td>
</tr>
<tr v-if="devis.length === 0">
<tr v-if="orderedDevis.length === 0">
<td colspan="7" class="px-6 py-12 text-center">
<div class="flex flex-col items-center justify-center text-slate-500 dark:text-slate-400">
<svg class="w-12 h-12 mb-4 text-slate-300 dark:text-slate-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">