From a82dcc0c92e97fbac9fc69fc0ca5ad989fc22b56 Mon Sep 17 00:00:00 2001 From: Jo Date: Fri, 17 Jul 2026 00:15:26 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20export=20Indy=20=E2=80=94=20selection?= =?UTF-8?q?=20commandes,=20CSV=20produits/services,=20acronyme=20client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 32 +++- templates/base.html | 3 + templates/client_form.html | 17 ++- templates/export_indy.html | 296 +++++++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+), 9 deletions(-) create mode 100644 templates/export_indy.html diff --git a/app.py b/app.py index c808d61..bcb7d53 100644 --- a/app.py +++ b/app.py @@ -309,6 +309,7 @@ def init_db(): 'ALTER TABLE jobs ADD COLUMN meshy_credits_used INTEGER DEFAULT 0', 'ALTER TABLE jobs ADD COLUMN meshy_cost REAL DEFAULT 0', 'ALTER TABLE jobs ADD COLUMN meshy_margin_pct REAL DEFAULT 0', + 'ALTER TABLE clients ADD COLUMN acronyme TEXT DEFAULT ""', ] for sql in migrations: try: @@ -845,10 +846,11 @@ def new_client(): if request.method == 'POST': def _int(k): return int(request.form[k]) if request.form.get(k) else None conn.execute('''INSERT INTO clients - (name,email,notes,default_machine_profile_id,default_handling_profile_id, + (name,acronyme,email,notes,default_machine_profile_id,default_handling_profile_id, default_material_profile_id,default_pricing_profile_id) - VALUES(?,?,?,?,?,?,?)''', - (request.form['name'], request.form.get('email',''), request.form.get('notes',''), + VALUES(?,?,?,?,?,?,?,?)''', + (request.form['name'], request.form.get('acronyme','').upper().strip(), + request.form.get('email',''), request.form.get('notes',''), _int('default_machine_profile_id'), _int('default_handling_profile_id'), _int('default_material_profile_id'), _int('default_pricing_profile_id'))) conn.commit(); conn.close() @@ -863,10 +865,11 @@ def edit_client(id): client = conn.execute('SELECT * FROM clients WHERE id=?',(id,)).fetchone() if request.method == 'POST': def _int(k): return int(request.form[k]) if request.form.get(k) else None - conn.execute('''UPDATE clients SET name=?,email=?,notes=?, + conn.execute('''UPDATE clients SET name=?,acronyme=?,email=?,notes=?, default_machine_profile_id=?,default_handling_profile_id=?, default_material_profile_id=?,default_pricing_profile_id=? WHERE id=?''', - (request.form['name'], request.form.get('email',''), request.form.get('notes',''), + (request.form['name'], request.form.get('acronyme','').upper().strip(), + request.form.get('email',''), request.form.get('notes',''), _int('default_machine_profile_id'), _int('default_handling_profile_id'), _int('default_material_profile_id'), _int('default_pricing_profile_id'), id)) conn.commit(); conn.close() @@ -897,6 +900,25 @@ def delete_client(id): conn.commit(); conn.close() return redirect(url_for('clients')) + +@app.route('/export/indy') +def export_indy(): + """Page d'export des commandes au format Indy (produits/services).""" + conn = get_db() + jobs = conn.execute(''' + SELECT j.id, j.name, j.created_at, j.final_price, j.discount_pct, + j.tva_amount, j.order_qty, j.pieces_per_plate, j.plate_name, + j.description, + c.name as client_name, c.acronyme as client_acronyme + FROM jobs j + LEFT JOIN clients c ON j.client_id = c.id + ORDER BY j.created_at DESC + ''').fetchall() + s = get_settings() + tva_pct = float(s.get('tva_rate_pct', 20.0)) + conn.close() + return render_template('export_indy.html', jobs=jobs, tva_pct=tva_pct) + # ─── Projets ────────────────────────────────────────────────────────────────── @app.route('/projects') diff --git a/templates/base.html b/templates/base.html index 194681d..a14e2fa 100644 --- a/templates/base.html +++ b/templates/base.html @@ -213,6 +213,9 @@ Statistiques + + Export Indy + Export CSV diff --git a/templates/client_form.html b/templates/client_form.html index dd28c19..b3ef74c 100644 --- a/templates/client_form.html +++ b/templates/client_form.html @@ -15,10 +15,19 @@
-
- - +
+
+ + +
+
+ + +
diff --git a/templates/export_indy.html b/templates/export_indy.html new file mode 100644 index 0000000..8c0b022 --- /dev/null +++ b/templates/export_indy.html @@ -0,0 +1,296 @@ +{% extends 'base.html' %} +{% block title %}Export Indy{% endblock %} + +{% block content %} + + +
+ + +
+
+
+ Selection des commandes +
+ + +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + + + + + + + + + {% for j in jobs %} + {% set prix_ttc = (j.final_price / (1 - j.discount_pct / 100)) if (j.discount_pct and j.discount_pct > 0 and j.discount_pct < 100) else (j.final_price or 0) %} + {% set prix_ht_net = prix_ttc - (j.tva_amount or 0) %} + {% set qty = j.order_qty or 1 %} + {% set acro = j.client_acronyme or '' %} + {% set default_nom = (acro ~ ' - ' ~ j.name) if acro else j.name %} + + + + + + {% endfor %} + +
CommandePrix HT
+
{{ j.name }}
+
+ {{ j.created_at[:10] }}{% if j.client_name %} · {{ j.client_name }}{% if acro %} {{ acro }}{% endif %}{% endif %} +
+
{{ '%.2f'|format(prix_ht_net) }} €
+
+
+
+ + +
+
+
+ Produits Indy 0 + +
+
+ + + + + + + + + + + + + + + + +
Nom produit (éditable)NaturePrix HTTVA %Unité
+ Sélectionnez des commandes +
+
+
+
+ + Les colonnes Nom, Nature, Prix HT, TVA et Unité sont éditables directement dans le tableau. + Le CSV généré est compatible avec l'import Produits & Services d'Indy. +
+
+ +
+ + +{% endblock %}