diff --git a/CHANGELOG.md b/CHANGELOG.md index d16c6be37..11dae5ae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to Bambuddy will be documented in this file. ## [0.1.9b] - Not released +### Fixed +- **Filament Usage Charts Inflated by Quantity Multiplier** ([#229](https://github.com/maziggy/bambuddy/issues/229)) — Daily, weekly, and filament-type charts were multiplying `filament_used_grams` by print quantity, even though the value already represents the total for the entire job. A 26-object print using 126g was counted as 3,276g. Removed the erroneous multiplier from three aggregations in `FilamentTrends.tsx`. + ### Testing - **Mock FTPS Server & Comprehensive FTP Test Suite** — Added 67 automated test cases against a real implicit FTPS mock server, covering every known FTP failure mode from 0.1.8+: - Mock server (`mock_ftp_server.py`) implements implicit TLS, custom AVBL command, and per-command failure injection diff --git a/frontend/src/components/FilamentTrends.tsx b/frontend/src/components/FilamentTrends.tsx index 98cfd071b..05fed434c 100644 --- a/frontend/src/components/FilamentTrends.tsx +++ b/frontend/src/components/FilamentTrends.tsx @@ -61,10 +61,9 @@ export function FilamentTrends({ archives, currency = '$' }: FilamentTrendsProps const key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; const existing = dataMap.get(key) || { date: key, filament: 0, cost: 0, prints: 0 }; - const qty = archive.quantity || 1; - existing.filament += (archive.filament_used_grams || 0) * qty; + existing.filament += archive.filament_used_grams || 0; existing.cost += archive.cost || 0; - existing.prints += qty; + existing.prints += archive.quantity || 1; dataMap.set(key, existing); }); @@ -90,10 +89,9 @@ export function FilamentTrends({ archives, currency = '$' }: FilamentTrendsProps const key = `${weekStart.getFullYear()}-${String(weekStart.getMonth() + 1).padStart(2, '0')}-${String(weekStart.getDate()).padStart(2, '0')}`; const existing = dataMap.get(key) || { week: key, filament: 0, cost: 0, prints: 0 }; - const qty = archive.quantity || 1; - existing.filament += (archive.filament_used_grams || 0) * qty; + existing.filament += archive.filament_used_grams || 0; existing.cost += archive.cost || 0; - existing.prints += qty; + existing.prints += archive.quantity || 1; dataMap.set(key, existing); }); @@ -112,11 +110,10 @@ export function FilamentTrends({ archives, currency = '$' }: FilamentTrendsProps filteredArchives.forEach(archive => { const type = archive.filament_type || 'Unknown'; - const qty = archive.quantity || 1; // Handle multiple types (e.g., "PLA, PETG") const types = type.split(', '); types.forEach(t => { - const grams = ((archive.filament_used_grams || 0) * qty) / types.length; + const grams = (archive.filament_used_grams || 0) / types.length; dataMap.set(t, (dataMap.get(t) || 0) + grams); }); });