Просмотр исходного кода

Fix filament usage charts inflated by quantity multiplier (fixes #229)

filament_used_grams already represents the total for the entire print
job. The daily, weekly, and filament-type charts were multiplying it
by quantity, e.g. a 26-object print using 126g was counted as 3,276g.

Removed the erroneous `* qty` from three aggregations in
FilamentTrends.tsx. Monthly comparison and summary cards were already
correct.

Fixes #229
maziggy 3 месяцев назад
Родитель
Сommit
cfd5dd66e5
2 измененных файлов с 8 добавлено и 8 удалено
  1. 3 0
      CHANGELOG.md
  2. 5 8
      frontend/src/components/FilamentTrends.tsx

+ 3 - 0
CHANGELOG.md

@@ -4,6 +4,9 @@ All notable changes to Bambuddy will be documented in this file.
 
 
 ## [0.1.9b] - Not released
 ## [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
 ### 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 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
   - Mock server (`mock_ftp_server.py`) implements implicit TLS, custom AVBL command, and per-command failure injection

+ 5 - 8
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 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 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.cost += archive.cost || 0;
-      existing.prints += qty;
+      existing.prints += archive.quantity || 1;
       dataMap.set(key, existing);
       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 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 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.cost += archive.cost || 0;
-      existing.prints += qty;
+      existing.prints += archive.quantity || 1;
       dataMap.set(key, existing);
       dataMap.set(key, existing);
     });
     });
 
 
@@ -112,11 +110,10 @@ export function FilamentTrends({ archives, currency = '$' }: FilamentTrendsProps
 
 
     filteredArchives.forEach(archive => {
     filteredArchives.forEach(archive => {
       const type = archive.filament_type || 'Unknown';
       const type = archive.filament_type || 'Unknown';
-      const qty = archive.quantity || 1;
       // Handle multiple types (e.g., "PLA, PETG")
       // Handle multiple types (e.g., "PLA, PETG")
       const types = type.split(', ');
       const types = type.split(', ');
       types.forEach(t => {
       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);
         dataMap.set(t, (dataMap.get(t) || 0) + grams);
       });
       });
     });
     });