239 lines
10 KiB
HTML
239 lines
10 KiB
HTML
{% extends 'base.html' %}
|
|
{% block title %}Templates / Profils{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="page-header d-flex justify-content-between align-items-center">
|
|
<h1><i class="bi bi-bookmark-star me-2" style="color:#ff6b35"></i>Templates & Profils</h1>
|
|
</div>
|
|
|
|
<ul class="nav nav-tabs mb-4" id="profileTabs" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if not request.args.get('tab') or request.args.get('tab')=='machine' %}active{% endif %}"
|
|
href="#machine" data-bs-toggle="tab" data-bs-target="#machine">
|
|
<i class="bi bi-cpu me-1"></i>Machine
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.args.get('tab')=='handling' %}active{% endif %}"
|
|
href="#handling" data-bs-toggle="tab" data-bs-target="#handling">
|
|
<i class="bi bi-hand-index me-1"></i>Manutention
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.args.get('tab')=='material' %}active{% endif %}"
|
|
href="#material" data-bs-toggle="tab" data-bs-target="#material">
|
|
<i class="bi bi-box me-1"></i>Matiere
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.args.get('tab')=='pricing' %}active{% endif %}"
|
|
href="#pricing" data-bs-toggle="tab" data-bs-target="#pricing">
|
|
<i class="bi bi-tags me-1"></i>Tarif client
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
|
|
<!-- Machine -->
|
|
<div class="tab-pane fade {% if not request.args.get('tab') or request.args.get('tab')=='machine' %}show active{% endif %}" id="machine">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<p class="text-muted mb-0 small">Imprimante, buse, plateau et electricite. Remplace les parametres globaux lors du calcul.</p>
|
|
<a href="{{ url_for('new_machine_profile') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">
|
|
<i class="bi bi-plus-lg me-1"></i>Nouveau
|
|
</a>
|
|
</div>
|
|
{% if machine_profiles %}
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>Imprimante</th>
|
|
<th>Buse</th>
|
|
<th>Plateau</th>
|
|
<th>Puissance</th>
|
|
<th>Electricite</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for p in machine_profiles %}
|
|
<tr>
|
|
<td class="fw-semibold">{{ p.name }}</td>
|
|
<td class="small text-muted">{{ p.printer_price }}€ / {{ p.printer_lifespan_hours|int }}h</td>
|
|
<td class="small text-muted">{{ p.nozzle_price }}€ / {{ p.nozzle_lifespan_hours|int }}h</td>
|
|
<td class="small text-muted">{{ p.plate_price }}€ / {{ p.plate_lifespan_hours|int }}h</td>
|
|
<td class="small text-muted">{{ p.printer_power_kw }} kW</td>
|
|
<td class="small text-muted">{{ p.electricity_price_kwh }} €/kWh</td>
|
|
<td class="text-end">
|
|
<a href="{{ url_for('edit_machine_profile', id=p.id) }}" class="btn btn-sm btn-outline-secondary py-0 me-1">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<form method="POST" action="{{ url_for('delete_machine_profile', id=p.id) }}" class="d-inline"
|
|
onsubmit="return confirm('Supprimer ce profil ?')">
|
|
<button class="btn btn-sm btn-outline-danger py-0"><i class="bi bi-trash"></i></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="card"><div class="card-body text-center text-muted py-4">
|
|
<i class="bi bi-cpu fs-2"></i><p class="mt-2 small">Aucun profil machine.</p>
|
|
</div></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Manutention -->
|
|
<div class="tab-pane fade {% if request.args.get('tab')=='handling' %}show active{% endif %}" id="handling">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<p class="text-muted mb-0 small">Taux horaire et temps de preparation par plateau.</p>
|
|
<a href="{{ url_for('new_handling_profile') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">
|
|
<i class="bi bi-plus-lg me-1"></i>Nouveau
|
|
</a>
|
|
</div>
|
|
{% if handling_profiles %}
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr><th>Nom</th><th>Taux horaire</th><th>Minutes / plateau</th><th>Cout fixe par job</th><th></th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for p in handling_profiles %}
|
|
{% set cost = (p.handling_rate_per_hour / 60) * p.handling_minutes_per_plate %}
|
|
<tr>
|
|
<td class="fw-semibold">{{ p.name }}</td>
|
|
<td>{{ p.handling_rate_per_hour }} €/h</td>
|
|
<td>{{ p.handling_minutes_per_plate }} min</td>
|
|
<td class="fw-semibold" style="color:#ff6b35">{{ "%.2f"|format(cost) }} €</td>
|
|
<td class="text-end">
|
|
<a href="{{ url_for('edit_handling_profile', id=p.id) }}" class="btn btn-sm btn-outline-secondary py-0 me-1">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<form method="POST" action="{{ url_for('delete_handling_profile', id=p.id) }}" class="d-inline"
|
|
onsubmit="return confirm('Supprimer ce profil ?')">
|
|
<button class="btn btn-sm btn-outline-danger py-0"><i class="bi bi-trash"></i></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="card"><div class="card-body text-center text-muted py-4">
|
|
<i class="bi bi-hand-index fs-2"></i><p class="mt-2 small">Aucun profil manutention.</p>
|
|
</div></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Matiere -->
|
|
<div class="tab-pane fade {% if request.args.get('tab')=='material' %}show active{% endif %}" id="material">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<p class="text-muted mb-0 small">Marge appliquee sur le cout matiere. Utile pour differencier les types de filament (standard, technique, flexible...).</p>
|
|
<a href="{{ url_for('new_material_profile') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">
|
|
<i class="bi bi-plus-lg me-1"></i>Nouveau
|
|
</a>
|
|
</div>
|
|
{% if material_profiles %}
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr><th>Nom</th><th>Marge matiere</th><th>Notes</th><th></th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for p in material_profiles %}
|
|
<tr>
|
|
<td class="fw-semibold">{{ p.name }}</td>
|
|
<td><span class="badge bg-secondary">{{ p.material_margin_pct }} %</span></td>
|
|
<td class="small text-muted">{{ p.notes or '' }}</td>
|
|
<td class="text-end">
|
|
<a href="{{ url_for('edit_material_profile', id=p.id) }}" class="btn btn-sm btn-outline-secondary py-0 me-1">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<form method="POST" action="{{ url_for('delete_material_profile', id=p.id) }}" class="d-inline"
|
|
onsubmit="return confirm('Supprimer ce profil ?')">
|
|
<button class="btn btn-sm btn-outline-danger py-0"><i class="bi bi-trash"></i></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="card"><div class="card-body text-center text-muted py-4">
|
|
<i class="bi bi-box fs-2"></i><p class="mt-2 small">Aucun profil matiere.</p>
|
|
</div></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Tarif client -->
|
|
<div class="tab-pane fade {% if request.args.get('tab')=='pricing' %}show active{% endif %}" id="pricing">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<p class="text-muted mb-0 small">Coefficient design et marge brute. Creer un profil par type de relation client.</p>
|
|
<a href="{{ url_for('new_pricing_profile') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">
|
|
<i class="bi bi-plus-lg me-1"></i>Nouveau
|
|
</a>
|
|
</div>
|
|
{% if pricing_profiles %}
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr><th>Nom</th><th>Coeff design</th><th>Marge brute</th><th>Notes</th><th></th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for p in pricing_profiles %}
|
|
<tr>
|
|
<td class="fw-semibold">{{ p.name }}</td>
|
|
<td><span class="badge bg-primary">x{{ p.design_multiplier }}</span></td>
|
|
<td><span class="badge" style="background:#ff6b35">{{ p.gross_margin_pct }} %</span></td>
|
|
<td class="small text-muted">{{ p.notes or '' }}</td>
|
|
<td class="text-end">
|
|
<a href="{{ url_for('edit_pricing_profile', id=p.id) }}" class="btn btn-sm btn-outline-secondary py-0 me-1">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<form method="POST" action="{{ url_for('delete_pricing_profile', id=p.id) }}" class="d-inline"
|
|
onsubmit="return confirm('Supprimer ce profil ?')">
|
|
<button class="btn btn-sm btn-outline-danger py-0"><i class="bi bi-trash"></i></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="card"><div class="card-body text-center text-muted py-4">
|
|
<i class="bi bi-tags fs-2"></i><p class="mt-2 small">Aucun profil tarif client.</p>
|
|
</div></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
// Activer l'onglet correspondant au hash ou query param
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const hash = window.location.hash;
|
|
if (hash) {
|
|
const tab = document.querySelector('[data-bs-target="' + hash + '"]');
|
|
if (tab) new bootstrap.Tab(tab).show();
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|