Merge pull request 'devel' (#1) from jblb/BillManager:devel into master

Reviewed-on: seb_vallee/BillManager#1
This commit is contained in:
2026-03-13 11:23:35 +01:00

277
templates/pdf/devis.html Normal file
View File

@@ -0,0 +1,277 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<style>
@page {
size: A4;
margin: 1.5cm 1.8cm;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'DejaVu Sans', Arial, sans-serif;
font-size: 10pt;
color: #1a1a1a;
}
.header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 2em;
padding-bottom: 1.5em;
border-bottom: 2px solid #2c3e50;
}
.emetteur h1 {
font-size: 16pt;
color: #2c3e50;
margin-bottom: 0.3em;
}
.emetteur p { font-size: 9pt; color: #555; line-height: 1.6; }
.facture-titre {
text-align: right;
}
.facture-titre h2 {
font-size: 22pt;
color: #2c3e50;
letter-spacing: 1px;
text-transform: uppercase;
}
.facture-titre .numero {
font-size: 13pt;
font-weight: bold;
color: #e74c3c;
margin-top: 0.2em;
}
.facture-titre .dates {
font-size: 9pt;
color: #555;
margin-top: 0.5em;
line-height: 1.8;
}
.parties {
display: flex;
justify-content: space-between;
margin-bottom: 2em;
gap: 2em;
}
.partie {
flex: 1;
padding: 1em;
border: 1px solid #ddd;
border-radius: 4px;
}
.partie h3 {
font-size: 8pt;
text-transform: uppercase;
letter-spacing: 1px;
color: #888;
margin-bottom: 0.7em;
border-bottom: 1px solid #eee;
padding-bottom: 0.4em;
}
.partie p { font-size: 9.5pt; line-height: 1.7; }
.partie .nom { font-weight: bold; font-size: 11pt; }
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.5em;
}
thead tr {
background-color: #2c3e50;
color: white;
}
thead th {
padding: 0.6em 0.8em;
text-align: left;
font-size: 9pt;
font-weight: normal;
text-transform: uppercase;
letter-spacing: 0.5px;
}
thead th:last-child { text-align: right; }
tbody tr:nth-child(even) { background: #f8f9fa; }
tbody td {
padding: 0.6em 0.8em;
font-size: 9.5pt;
border-bottom: 1px solid #eee;
vertical-align: top;
}
tbody td:last-child { text-align: right; font-weight: 500; }
td.qte { text-align: center; }
td.pu { text-align: right; }
.totaux {
display: flex;
justify-content: flex-end;
margin-bottom: 2em;
}
.totaux table {
width: auto;
min-width: 280px;
}
.totaux td {
padding: 0.4em 0.8em;
font-size: 10pt;
border: none;
}
.totaux tr.total-ht td {
font-size: 12pt;
font-weight: bold;
color: #2c3e50;
border-top: 2px solid #2c3e50;
padding-top: 0.6em;
}
.totaux td:last-child { text-align: right; }
.tva-mention {
font-size: 8.5pt;
color: #666;
font-style: italic;
text-align: right;
margin-bottom: 1.5em;
}
.footer-info {
border-top: 1px solid #ddd;
padding-top: 1em;
font-size: 8.5pt;
color: #555;
line-height: 1.7;
}
.footer-info .conditions {
margin-bottom: 0.5em;
}
.footer-info .penalites {
font-size: 8pt;
color: #888;
}
.footer-info .iban {
margin-top: 0.5em;
font-weight: bold;
}
.devis-ref {
font-size: 8.5pt;
color: #888;
margin-bottom: 1.5em;
}
.notes {
background: #f8f9fa;
border-left: 3px solid #2c3e50;
padding: 0.7em 1em;
font-size: 9pt;
margin-bottom: 1.5em;
color: #444;
}
</style>
</head>
<body>
<!-- EN-TÊTE -->
<div class="header">
<div class="emetteur">
<h1>{{ settings.asso_nom }}</h1>
<p>
{{ settings.asso_adresse }}<br>
{{ settings.asso_code_postal }} {{ settings.asso_ville }}<br>
{% if settings.asso_email %}{{ settings.asso_email }}<br>{% endif %}
{% if settings.asso_telephone %}{{ settings.asso_telephone }}<br>{% endif %}
{% if settings.asso_rna %}RNA : {{ settings.asso_rna }}<br>{% endif %}
{% if settings.asso_siret %}SIRET : {{ settings.asso_siret }}{% endif %}
</p>
</div>
<div class="facture-titre">
<h2>Devis</h2>
<div class="numero">N° {{ devis.numero }}</div>
<div class="dates">
Date d'émission : {{ devis.date_emission.strftime('%d/%m/%Y') }}<br>
Date d'échéance : {{ devis.date_validite.strftime('%d/%m/%Y') }}
</div>
</div>
</div>
<!-- PARTIES -->
<div class="parties">
<div class="partie">
<h3>Émetteur</h3>
<p>
<span class="nom">{{ settings.asso_nom }}</span><br>
{{ settings.asso_adresse }}<br>
{{ settings.asso_code_postal }} {{ settings.asso_ville }}<br>
{% if settings.asso_rna %}RNA : {{ settings.asso_rna }}<br>{% endif %}
{% if settings.asso_siret %}SIRET : {{ settings.asso_siret }}{% endif %}
</p>
</div>
<div class="partie">
<h3>Destinataire</h3>
<p>
<span class="nom">{{ devis.client.nom }}</span><br>
{{ devis.client.adresse }}<br>
{{ devis.client.code_postal }} {{ devis.client.ville }}
{% if devis.client.siret %}<br>SIRET : {{ devis.client.siret }}{% endif %}
{% if devis.client.email %}<br>{{ devis.client.email }}{% endif %}
</p>
</div>
</div>
<!-- LIGNES -->
<table>
<thead>
<tr>
<th style="width:55%">Désignation</th>
<th style="width:10%" class="qte">Qté</th>
<th style="width:17%">Prix unitaire HT</th>
<th style="width:18%">Total HT</th>
</tr>
</thead>
<tbody>
{% for l in devis.lignes %}
<tr>
<td>{{ l.description }}</td>
<td class="qte">
{% if l.quantite == l.quantite | int %}{{ l.quantite | int }}{% else %}{{ l.quantite }}{% endif %}
</td>
<td class="pu">
{{ "%.2f"|format(l.prix_unitaire_ht) | replace('.', ',') }} €
</td>
<td>{{ "%.2f"|format(l.total_ht) | replace('.', ',') }} €</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- TOTAUX -->
<div class="totaux">
<table>
<tr>
<td>Montant HT</td>
<td>{{ "%.2f"|format(devis.total_ht) | replace('.', ',') }} €</td>
</tr>
<tr>
<td>TVA</td>
<td>0,00 €</td>
</tr>
<tr class="total-ht">
<td>Total TTC</td>
<td>{{ "%.2f"|format(devis.total_ht) | replace('.', ',') }} €</td>
</tr>
</table>
</div>
<p class="tva-mention">TVA non applicable — art. 293B du CGI</p>
<!-- PIED DE PAGE LÉGAL -->
<div class="footer-info">
{% if settings.asso_iban %}
<div class="iban">
Coordonnées bancaires — IBAN : {{ settings.asso_iban }}
{% if settings.asso_bic %} — BIC : {{ settings.asso_bic }}{% endif %}
</div>
{% endif %}
</div>
</body>
</html>