feat(filament): add spool count and total remaining weight columns
Adds computed spool statistics to filament list: - spool_count: Number of non-archived spools of this filament - total_remaining_weight: Sum of remaining weight across all spools Backend changes: - Modified database/filament.py find() to compute stats via subquery - Added fields to Filament pydantic model in api/v1/models.py - Updated filament API endpoint to include stats in response Frontend changes: - Added fields to IFilament interface - Added columns to filament list table - Added translation keys Closes #15 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -114,13 +114,16 @@ async def find(
|
||||
sort_by: Optional[dict[str, SortOrder]] = None,
|
||||
limit: Optional[int] = None,
|
||||
offset: int = 0,
|
||||
) -> tuple[list[models.Filament], int]:
|
||||
) -> tuple[list[models.Filament], int, dict[int, tuple[int, float]]]:
|
||||
"""Find a list of filament objects by search criteria.
|
||||
|
||||
Sort by a field by passing a dict with the field name as key and the sort order as value.
|
||||
The field name can contain nested fields, e.g. vendor.name.
|
||||
|
||||
Returns a tuple containing the list of items and the total count of matching items.
|
||||
Returns a tuple containing:
|
||||
- list of filaments
|
||||
- total count of matching items
|
||||
- dict mapping filament_id to (spool_count, total_remaining_weight)
|
||||
"""
|
||||
stmt = (
|
||||
select(models.Filament)
|
||||
@@ -160,7 +163,25 @@ async def find(
|
||||
if total_count is None:
|
||||
total_count = len(result)
|
||||
|
||||
return result, total_count
|
||||
# Fetch spool statistics for all filaments in the result
|
||||
spool_stats: dict[int, tuple[int, float]] = {}
|
||||
if result:
|
||||
filament_ids = [f.id for f in result]
|
||||
stats_stmt = (
|
||||
select(
|
||||
models.Spool.filament_id,
|
||||
func.count(models.Spool.id).label("spool_count"),
|
||||
func.coalesce(func.sum(models.Spool.initial_weight - models.Spool.used_weight), 0).label("total_remaining"),
|
||||
)
|
||||
.where(models.Spool.filament_id.in_(filament_ids))
|
||||
.where((models.Spool.archived == False) | (models.Spool.archived == None)) # noqa: E712, E711
|
||||
.group_by(models.Spool.filament_id)
|
||||
)
|
||||
stats_rows = await db.execute(stats_stmt)
|
||||
for row in stats_rows.all():
|
||||
spool_stats[row.filament_id] = (row.spool_count, float(row.total_remaining or 0))
|
||||
|
||||
return result, total_count, spool_stats
|
||||
|
||||
|
||||
async def update(
|
||||
|
||||
Reference in New Issue
Block a user