feat(Devis): Ajoute options, dates début/fin et améliore affichage PDF

Ajoute les champs date de début et fin au devis. Permet l'ajout d'options au devis. Améliore l'affichage du PDF.
```
This commit is contained in:
Serreau Jovann
2026-01-22 10:36:26 +01:00
parent 1d7102ec07
commit 7dc2978094
20 changed files with 646 additions and 111 deletions

View File

@@ -57,6 +57,7 @@
{{ form_label(form.customer, null, {'label_attr': {'class': label_class}}) }}
{{ form_widget(form.customer, {'attr': {'class': input_class}}) }}
</div>
</div>
{# SECTION ADRESSES #}
@@ -70,6 +71,17 @@
<select id="shipAddress" name="devis[ship_address]" class="{{ input_class }}"></select>
</div>
</div>
{# SECTION ADRESSES #}
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="space-y-3">
{{ form_label(form.startAt, null, {'label_attr': {'class': label_class}}) }}
{{ form_widget(form.startAt, {'attr': {'class': input_class}}) }}
</div>
<div class="space-y-3">
{{ form_label(form.endAt, null, {'label_attr': {'class': label_class}}) }}
{{ form_widget(form.endAt, {'attr': {'class': input_class}}) }}
</div>
</div>
<hr class="border-white/5">
@@ -86,7 +98,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-5 items-end">
{# 1. PRODUIT #}
<div class="lg:col-span-3">
<div class="lg:col-span-5">
<label class="{{ label_class }}">Produit / Prestation</label>
<select data-load="product" name="lines[0][product_id]" class="{{ input_class }}" required>
<option value="">Sélectionner...</option>
@@ -94,7 +106,7 @@
</div>
{# 2. DURÉE #}
<div class="lg:col-span-1">
<div class="lg:col-span-2">
<label class="{{ label_class }}">Jours</label>
<input type="number" name="lines[0][days]" min="1" placeholder="1" class="{{ input_class }} [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" required />
</div>
@@ -106,22 +118,11 @@
</div>
{# 4. PRIX HT SUP #}
<div class="lg:col-span-1">
<div class="lg:col-span-2">
<label class="{{ label_class }}">HT Sup</label>
<input type="number" step="0.01" name="lines[0][price_sup_ht]" placeholder="0.00" class="{{ input_class }} text-right font-mono" required />
</div>
{# 5. DATES #}
<div class="lg:col-span-2">
<label class="{{ label_class }}">Date Début</label>
<input type="date" name="lines[0][date_start]" class="{{ input_class }} [color-scheme:dark]" required />
</div>
<div class="lg:col-span-2">
<label class="{{ label_class }}">Date Fin</label>
<input type="date" name="lines[0][date_end]" class="{{ input_class }} [color-scheme:dark]" required />
</div>
{# 6. SUPPRIMER #}
<div class="lg:col-span-1 flex justify-center pb-1">
<button type="button" data-ref="removeButton" class="p-4 bg-red-500/10 hover:bg-red-500 text-red-500 hover:text-white rounded-2xl transition-all duration-300 shadow-lg hover:shadow-red-500/20">
@@ -143,6 +144,47 @@
</div>
</div>
<div class="form-repeater" data-component="repeater2" is="repeat-line">
<div class="flex items-center justify-between mb-6 px-4">
<h4 class="text-sm font-black text-white uppercase tracking-widest">Détail des options</h4>
</div>
<ol class="form-repeater__rows space-y-4" data-ref="rows">
<li class="form-repeater__row group animate-in slide-in-from-right-5 duration-300">
<fieldset class="backdrop-blur-md bg-white/5 border border-white/10 rounded-[2.5rem] p-8 hover:border-blue-500/30 transition-all shadow-xl">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-5 items-end">
{# 1. PRODUIT #}
<div class="lg:col-span-9">
<label class="{{ label_class }}">Options</label>
<select data-load="options" name="options[0][product_id]" class="{{ input_class }}" required>
<option value="">Sélectionner...</option>
</select>
</div>
{# 3. PRIX HT J1 #}
<div class="lg:col-span-2">
<label class="{{ label_class }}">Prix Ht (€)</label>
<input type="number" step="0.01" name="options[0][price_ht]" placeholder="0.00" class="{{ input_class }} text-right font-mono" required />
</div>
{# 6. SUPPRIMER #}
<div class="lg:col-span-1 flex justify-center pb-1">
<button type="button" data-ref="removeButton" class="p-4 bg-red-500/10 hover:bg-red-500 text-red-500 hover:text-white rounded-2xl transition-all duration-300 shadow-lg hover:shadow-red-500/20">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
</div>
</div>
</fieldset>
</li>
</ol>
<div class="mt-6 px-4">
<button type="button" data-ref="addButton" class="w-full py-4 border-2 border-dashed border-white/10 hover:border-purple-500/50 bg-white/5 hover:bg-purple-500/10 rounded-3xl text-purple-400 text-[10px] font-black uppercase tracking-[0.4em] transition-all flex items-center justify-center space-x-3 group">
<span class="text-xl group-hover:rotate-90 transition-transform duration-300">+</span>
<span>Ajouter une option</span>
</button>
</div>
</div>
{# VALIDATION #}
<div class="pt-8 px-4">
<button type="submit" class="w-full py-6 bg-blue-600 hover:bg-blue-500 text-white text-[11px] font-black uppercase tracking-[0.5em] rounded-[2rem] shadow-2xl shadow-blue-600/30 transition-all hover:scale-[1.01] active:scale-95 flex items-center justify-center group">