feat: plate_name + pieces auto-fill + object names from 3MF
Deploy via Portainer / deploy (push) Successful in 0s

This commit is contained in:
Jo
2026-07-07 09:56:05 +02:00
parent d160686e0c
commit b571a5ef0c
3 changed files with 66 additions and 14 deletions
+24 -7
View File
@@ -151,7 +151,7 @@ def init_db():
handling_profile_id INTEGER REFERENCES handling_profiles(id) ON DELETE SET NULL,
material_profile_id INTEGER REFERENCES material_profiles(id) ON DELETE SET NULL,
pricing_profile_id INTEGER REFERENCES pricing_profiles(id) ON DELETE SET NULL,
source_file TEXT DEFAULT '', name TEXT NOT NULL,
source_file TEXT DEFAULT '', plate_name TEXT DEFAULT '', name TEXT NOT NULL,
description TEXT DEFAULT '', weight_g REAL NOT NULL,
print_time_s INTEGER NOT NULL, design_multiplier REAL NOT NULL,
gross_margin_pct REAL NOT NULL DEFAULT 27.5, discount_pct REAL DEFAULT 0,
@@ -259,6 +259,7 @@ def init_db():
'ALTER TABLE print_slots ADD COLUMN wasted_g REAL DEFAULT 0',
'ALTER TABLE materials ADD COLUMN total_wasted_g REAL DEFAULT 0',
'ALTER TABLE jobs ADD COLUMN client_token TEXT DEFAULT NULL',
'ALTER TABLE jobs ADD COLUMN plate_name TEXT DEFAULT ""',
]
for sql in migrations:
try:
@@ -304,6 +305,7 @@ def parse_3mf(file_stream):
meta = {m.get('key'): m.get('value') for m in plate_el.findall('metadata')}
plate['index'] = int(meta.get('index', 0))
plate['print_time_s'] = int(meta.get('prediction', 0))
plate['name'] = meta.get('name', '') or ''
filaments = []
total_g = 0.0
@@ -317,12 +319,26 @@ def parse_3mf(file_stream):
'used_g': round(used_g, 2),
'used_m': round(float(fil.get('used_m', 0) or 0), 2),
})
plate['weight_g'] = round(total_g, 2)
plate['filaments'] = filaments
plate['weight_g'] = round(total_g, 2)
plate['filaments'] = filaments
# Pièces : compter les <object> non skippés
objs = [o for o in plate_el.findall('object') if o.get('skipped') != 'true']
plate['pieces'] = len(objs)
# Noms uniques des modèles (sans extension)
plate['object_names'] = list(dict.fromkeys(
o.get('name', '').rsplit('.', 1)[0]
for o in objs if o.get('name')
))
# Libellé lisible
h = plate['print_time_s'] // 3600
mn = (plate['print_time_s'] % 3600) // 60
plate['label'] = f"Plateau {plate['index']}{plate['weight_g']} g — {h}h{mn:02d}m"
name_part = f" «{plate['name']}»" if plate['name'] else ''
plate['label'] = (
f"Plateau {plate['index']}{name_part}"
f"{plate['weight_g']} g"
f"{h}h{mn:02d}m"
f"{plate['pieces']} pce(s)"
)
result['plates'].append(plate)
result['plates'].sort(key=lambda p: p['index'])
except Exception:
@@ -1157,6 +1173,7 @@ def new_job():
project_id = request.form.get('project_id') or None
pieces_per_plate = max(1, int(request.form.get('pieces_per_plate', 1)))
order_qty = max(1, int(request.form.get('order_qty', 1)))
plate_name = request.form.get('plate_name', '').strip()
s = dict(settings)
if machine_pid:
@@ -1189,16 +1206,16 @@ def new_job():
r = calc(weight_g, print_time_s, design_mult, gross_margin, discount,
price_kg, s, pieces_per_plate)
conn.execute('''INSERT INTO jobs(client_id,material_id,machine_profile_id,handling_profile_id,
material_profile_id,pricing_profile_id,project_id,source_file,name,description,
material_profile_id,pricing_profile_id,project_id,source_file,plate_name,name,description,
weight_g,print_time_s,design_multiplier,gross_margin_pct,discount_pct,
pieces_per_plate,order_qty,
material_cost,material_margin,design_cost,handling_cost,wear_cost,electricity_cost,
cout_fixe,total_marge,subtotal,margin_amount,
cotisations_amount,vfl_amount,tva_amount,other_taxes_amount,tax_amount,
price_per_piece,final_price,notes)
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
(client_id,material_id,machine_pid,handling_pid,material_pid,pricing_pid,project_id,
source_file,request.form['name'],request.form.get('description',''),
source_file,plate_name,request.form['name'],request.form.get('description',''),
weight_g,print_time_s,design_mult,gross_margin,discount,
pieces_per_plate,order_qty,
r['material_cost'],r['material_margin'],r['design_cost'],r['handling_cost'],