Add cost/time estimate card to job detail page
app/estimation.py: - 20% infill → material volume → weight (density per material) - print time at 20 g/h (conservative FDM average) - filament cost at FILAMENT_PRICE_PER_KG EUR/kg (env, default 15) - +20% misprint buffer, +30% gross profit margin - net price (ex. VAT) and gross price (VAT_RATE %, env, default 19) Card shows three columns: Material & Time / Production cost / Suggested price. Only rendered when STL volume is available. Assumptions shown in card header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,66 @@
|
||||
|
||||
</div>
|
||||
|
||||
{# ── Estimate ── #}
|
||||
{% if estimation %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header text-secondary small text-uppercase fw-normal" style="border-color:#21262d">
|
||||
Estimate
|
||||
<span class="text-secondary fw-normal ms-2" style="font-size:.7rem">
|
||||
20 % infill · {{ estimation.price_per_kg }} €/kg · {{ estimation.vat_rate }}% VAT
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="text-secondary small mb-2">Material & Time</div>
|
||||
<table class="table table-dark table-sm mb-0" style="font-size:.875rem">
|
||||
<tbody>
|
||||
<tr><td class="text-secondary border-0">Volume used</td>
|
||||
<td class="border-0">{{ estimation.material_ccm }} cm³</td></tr>
|
||||
<tr><td class="text-secondary">Weight</td>
|
||||
<td>{{ estimation.weight_g }} g</td></tr>
|
||||
<tr><td class="text-secondary">Print time</td>
|
||||
<td>
|
||||
{% set h = (estimation.print_minutes // 60) %}
|
||||
{% set m = (estimation.print_minutes % 60) %}
|
||||
{% if h %}{{ h }}h {% endif %}{{ m }}min
|
||||
<span class="text-secondary" style="font-size:.75rem">(est.)</span>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="text-secondary small mb-2">Production cost</div>
|
||||
<table class="table table-dark table-sm mb-0" style="font-size:.875rem">
|
||||
<tbody>
|
||||
<tr><td class="text-secondary border-0">Filament</td>
|
||||
<td class="border-0">{{ "%.2f"|format(estimation.filament_cost) }} €</td></tr>
|
||||
<tr><td class="text-secondary">+ 20 % misprint</td>
|
||||
<td>{{ "%.2f"|format(estimation.filament_cost * 1.2) }} €</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="text-secondary small mb-2">Suggested price</div>
|
||||
<table class="table table-dark table-sm mb-0" style="font-size:.875rem">
|
||||
<tbody>
|
||||
<tr><td class="text-secondary border-0">Net (ex. VAT)</td>
|
||||
<td class="border-0 fw-medium text-white">{{ "%.2f"|format(estimation.net_price) }} €</td></tr>
|
||||
<tr><td class="text-secondary">Gross ({{ estimation.vat_rate }}% VAT)</td>
|
||||
<td class="fw-medium text-white">{{ "%.2f"|format(estimation.gross_price) }} €</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ── Log ── #}
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<h6 class="text-white mb-0">Log</h6>
|
||||
|
||||
Reference in New Issue
Block a user