Templates, decomposition prix restructuree, TVA + VFL, fix DM buttons

This commit is contained in:
Jo
2026-07-06 12:40:10 +02:00
parent ad198a1756
commit b25c3d9170
11 changed files with 1311 additions and 152 deletions
+63 -25
View File
@@ -22,7 +22,7 @@
<div class="card-body">
<table class="table table-sm mb-0">
<tr><th class="text-muted fw-normal" style="width:45%">Client</th><td>{{ job.client_name or '—' }}</td></tr>
<tr><th class="text-muted fw-normal">Matière</th>
<tr><th class="text-muted fw-normal">Matiere</th>
<td>
{% if job.material_name %}
<span class="badge bg-secondary">{{ job.material_type }}</span> {{ job.material_name }}
@@ -30,13 +30,22 @@
</td>
</tr>
<tr><th class="text-muted fw-normal">Fichier source</th>
<td class="text-monospace small">{{ job.source_file or '—' }}</td></tr>
<td class="small font-monospace">{{ job.source_file or '—' }}</td></tr>
<tr><th class="text-muted fw-normal">Date</th><td>{{ job.created_at[:10] }}</td></tr>
<tr><th class="text-muted fw-normal">Poids filament</th><td>{{ job.weight_g }} g</td></tr>
<tr><th class="text-muted fw-normal">Durée impression</th><td>{{ job.print_time_s | fmt_time }}</td></tr>
<tr><th class="text-muted fw-normal">Duree impression</th><td>{{ job.print_time_s | fmt_time }}</td></tr>
<tr><th class="text-muted fw-normal">Coeff design</th><td>×{{ job.design_multiplier }}</td></tr>
<tr><th class="text-muted fw-normal">Marge brute</th><td>{{ job.gross_margin_pct }} %</td></tr>
<tr><th class="text-muted fw-normal">Remise</th><td>{{ job.discount_pct }} %</td></tr>
{% if job.machine_profile_name %}
<tr><th class="text-muted fw-normal">Profil machine</th><td>{{ job.machine_profile_name }}</td></tr>
{% endif %}
{% if job.handling_profile_name %}
<tr><th class="text-muted fw-normal">Profil manutention</th><td>{{ job.handling_profile_name }}</td></tr>
{% endif %}
{% if job.pricing_profile_name %}
<tr><th class="text-muted fw-normal">Profil tarif</th><td>{{ job.pricing_profile_name }}</td></tr>
{% endif %}
</table>
{% if job.notes %}
<hr>
@@ -48,30 +57,56 @@
<div class="col-md-7">
<div class="card">
<div class="card-header py-3"><i class="bi bi-receipt me-2"></i>Décomposition du prix</div>
<div class="card-header py-3"><i class="bi bi-receipt me-2"></i>Decomposition du prix</div>
<div class="card-body">
<div class="breakdown-row"><span class="breakdown-muted">Matière</span><span>{{ "%.4f"|format(job.material_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted">Marge matière</span><span>{{ "%.4f"|format(job.material_margin) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted">Design (×{{ job.design_multiplier }})</span><span>{{ "%.4f"|format(job.design_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted">Manutention</span><span>{{ "%.4f"|format(job.handling_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted">Usure machine</span><span>{{ "%.4f"|format(job.wear_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted">Électricité</span><span>{{ "%.4f"|format(job.electricity_cost) }} €</span></div>
<!-- Cout fixe -->
<div class="breakdown-row section-header"><span>Cout fixe</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Matiere</span><span>{{ "%.4f"|format(job.material_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Marge matiere</span><span>{{ "%.4f"|format(job.material_margin) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Usure machine</span><span>{{ "%.4f"|format(job.wear_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Electricite</span><span>{{ "%.4f"|format(job.electricity_cost) }} €</span></div>
<div class="breakdown-row subtotal">
<span class="fw-semibold">Sous-total coûts</span>
<span class="fw-semibold">{{ "%.2f"|format(job.subtotal) }} €</span>
<span class="fw-semibold">Total cout fixe</span>
<span class="fw-semibold">
{% if job.cout_fixe %}{{ "%.2f"|format(job.cout_fixe) }}{% else %}{{ "%.2f"|format(job.material_cost + job.material_margin + job.wear_cost + job.electricity_cost) }}{% endif %} €
</span>
</div>
<!-- Partie variable -->
<div class="breakdown-row section-header"><span>Partie variable</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Manutention</span><span>{{ "%.4f"|format(job.handling_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Design (×{{ job.design_multiplier }})</span><span>{{ "%.4f"|format(job.design_cost) }} €</span></div>
<div class="breakdown-row"><span class="breakdown-muted ps-2">Marge brute ({{ job.gross_margin_pct }}%)</span><span>{{ "%.2f"|format(job.margin_amount) }} €</span></div>
<div class="breakdown-row subtotal">
<span class="fw-semibold">Total marge</span>
<span class="fw-semibold">
{% if job.total_marge %}{{ "%.2f"|format(job.total_marge) }}{% else %}{{ "%.2f"|format(job.handling_cost + job.design_cost + job.margin_amount) }}{% endif %} €
</span>
</div>
<!-- Fiscal -->
<div class="breakdown-row section-header"><span>Fiscal</span></div>
<div class="breakdown-row">
<span class="breakdown-muted">Marge brute ({{ job.gross_margin_pct }}%)</span>
<span>{{ "%.2f"|format(job.margin_amount) }} €</span>
<span class="breakdown-muted ps-2">Cotisations sociales</span>
<span>{% if job.cotisations_amount %}{{ "%.2f"|format(job.cotisations_amount) }}{% else %}{{ "%.2f"|format(job.tax_amount) }}{% endif %} €</span>
</div>
{% if job.vfl_amount and job.vfl_amount > 0 %}
<div class="breakdown-row">
<span class="breakdown-muted">Cotisations micro-ent.</span>
<span>{{ "%.2f"|format(job.tax_amount) }} €</span>
<span class="breakdown-muted ps-2">VFL impot</span>
<span>{{ "%.2f"|format(job.vfl_amount) }} €</span>
</div>
{% endif %}
{% if job.tva_amount and job.tva_amount > 0 %}
<div class="breakdown-row">
<span class="breakdown-muted ps-2">TVA</span>
<span>{{ "%.2f"|format(job.tva_amount) }} €</span>
</div>
{% endif %}
{% if job.discount_pct > 0 %}
<div class="breakdown-row text-danger">
<span>Remise ({{ job.discount_pct }}%)</span>
<span>{{ "%.2f"|format((job.subtotal + job.margin_amount + job.tax_amount) * job.discount_pct / 100) }} €</span>
<span class="ps-2">Remise ({{ job.discount_pct }}%)</span>
<span>{{ "%.2f"|format(job.final_price / (1 - job.discount_pct/100) * (job.discount_pct/100)) }} €</span>
</div>
{% endif %}
<div class="breakdown-row total">
@@ -80,18 +115,21 @@
</div>
<!-- Barre de composition -->
{% set total = job.final_price %}
{% set cout_f = job.cout_fixe or (job.material_cost + job.material_margin + job.wear_cost + job.electricity_cost) %}
{% set tot_m = job.total_marge or (job.handling_cost + job.design_cost + job.margin_amount) %}
{% set fiscal = (job.cotisations_amount or job.tax_amount or 0) + (job.vfl_amount or 0) + (job.tva_amount or 0) %}
{% set total = job.final_price %}
{% if total > 0 %}
<div class="mt-4">
<div class="d-flex justify-content-between small text-muted mb-1">
<span>Coûts ({{ (job.subtotal/total*100)|round(1) }}%)</span>
<span>Marge ({{ (job.margin_amount/total*100)|round(1) }}%)</span>
<span>Taxes ({{ (job.tax_amount/total*100)|round(1) }}%)</span>
<span>Cout fixe ({{ (cout_f/total*100)|round(1) }}%)</span>
<span>Marge ({{ (tot_m/total*100)|round(1) }}%)</span>
<span>Fiscal ({{ (fiscal/total*100)|round(1) }}%)</span>
</div>
<div class="progress" style="height:18px;border-radius:6px">
<div class="progress-bar bg-secondary" style="width:{{ (job.subtotal/total*100)|round(1) }}%"></div>
<div class="progress-bar" style="width:{{ (job.margin_amount/total*100)|round(1) }}%;background:#ff6b35"></div>
<div class="progress-bar bg-warning text-dark" style="width:{{ (job.tax_amount/total*100)|round(1) }}%"></div>
<div class="progress-bar bg-secondary" style="width:{{ (cout_f/total*100)|round(1) }}%"></div>
<div class="progress-bar" style="width:{{ (tot_m/total*100)|round(1) }}%;background:#ff6b35"></div>
<div class="progress-bar bg-warning text-dark" style="width:{{ (fiscal/total*100)|round(1) }}%"></div>
</div>
</div>
{% endif %}