diff --git a/app.py b/app.py
index ed69b33..812073b 100644
--- a/app.py
+++ b/app.py
@@ -219,6 +219,7 @@ def init_db():
('nc_username',''),
('nc_app_password',''),
('nc_root_path','/3D'),
+ ('ical_token',''),
]
conn.executemany('INSERT OR IGNORE INTO settings VALUES (?,?)', defaults)
@@ -1364,11 +1365,36 @@ def mobile_quick():
except Exception:
pass
elif action == 'fail':
- slot_id = request.form.get('slot_id')
- note = request.form.get('failure_note', '')
+ slot_id = request.form.get('slot_id')
+ note = request.form.get('failure_note', '')
+ wasted_g = float(request.form.get('wasted_g', 0) or 0)
if slot_id:
- conn.execute("UPDATE print_slots SET status='failed',failure_note=? WHERE id=?",
- (note, slot_id))
+ slot = conn.execute('''
+ SELECT ps.weight_g as plate_g, j.material_id, j.weight_g
+ FROM print_slots ps JOIN jobs j ON ps.job_id=j.id
+ WHERE ps.id=?''', (slot_id,)).fetchone()
+ if slot:
+ if wasted_g == 0:
+ wasted_g = slot['weight_g'] or 0
+ conn.execute(
+ "UPDATE print_slots SET status='failed', failure_note=?, wasted_g=? WHERE id=?",
+ (note, wasted_g, slot_id))
+ if slot['material_id'] and wasted_g > 0:
+ conn.execute(
+ 'UPDATE materials SET stock_g=MAX(0,stock_g-?), total_wasted_g=COALESCE(total_wasted_g,0)+? WHERE id=?',
+ (wasted_g, wasted_g, slot['material_id']))
+ conn.commit()
+ elif action == 'done':
+ slot_id = request.form.get('slot_id')
+ actual_g = float(request.form.get('actual_g', 0) or 0)
+ if slot_id:
+ slot = conn.execute(
+ 'SELECT j.material_id FROM print_slots ps JOIN jobs j ON ps.job_id=j.id WHERE ps.id=?',
+ (slot_id,)).fetchone()
+ conn.execute("UPDATE print_slots SET status='done' WHERE id=?", (slot_id,))
+ if slot and slot['material_id'] and actual_g > 0:
+ conn.execute('UPDATE materials SET stock_g=MAX(0,stock_g-?) WHERE id=?',
+ (actual_g, slot['material_id']))
conn.commit()
conn.close()
return redirect(url_for('mobile_quick'))
@@ -1975,8 +2001,28 @@ def stats():
ROUND(SUM(j.weight_g),1) as total_g, ROUND(SUM(j.final_price),2) as revenue
FROM jobs j LEFT JOIN materials m ON j.material_id=m.id
GROUP BY j.material_id ORDER BY total_g DESC''').fetchall()
+ waste_by_material = conn.execute('''
+ SELECT COALESCE(m.name,'Non défini') as name, m.type,
+ COALESCE(m.color,'') as color,
+ ROUND(COALESCE(m.total_wasted_g,0),1) as wasted_g,
+ ROUND(COALESCE(m.stock_g,0),1) as stock_g
+ FROM materials m
+ WHERE COALESCE(m.total_wasted_g,0) > 0
+ ORDER BY wasted_g DESC''').fetchall()
+ failure_by_printer = conn.execute('''
+ SELECT COALESCE(p.name,'Inconnu') as name,
+ COUNT(ps.id) as total_slots,
+ SUM(CASE WHEN ps.status='failed' THEN 1 ELSE 0 END) as failed_slots,
+ ROUND(SUM(COALESCE(ps.wasted_g,0)),1) as wasted_g
+ FROM print_slots ps
+ LEFT JOIN printers p ON ps.printer_id=p.id
+ GROUP BY ps.printer_id
+ HAVING total_slots > 0
+ ORDER BY failed_slots DESC''').fetchall()
conn.close()
- return render_template('stats.html', by_client=by_client, by_month=by_month, by_material=by_material)
+ return render_template('stats.html', by_client=by_client, by_month=by_month,
+ by_material=by_material, waste_by_material=waste_by_material,
+ failure_by_printer=failure_by_printer)
# ─── Export CSV ───────────────────────────────────────────────────────────────
diff --git a/templates/base.html b/templates/base.html
index 7fe56a5..bd9d973 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -7,35 +7,73 @@