| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- from fastapi import APIRouter, Depends, HTTPException
- from sqlalchemy import select
- from sqlalchemy.ext.asyncio import AsyncSession
- from backend.app.core.auth import RequirePermissionIfAuthEnabled
- from backend.app.core.database import get_db
- from backend.app.core.permissions import Permission
- from backend.app.models.filament import Filament
- from backend.app.models.user import User
- from backend.app.schemas.filament import (
- FilamentCostCalculation,
- FilamentCreate,
- FilamentResponse,
- FilamentUpdate,
- )
- router = APIRouter(prefix="/filaments", tags=["filaments"])
- @router.get("/", response_model=list[FilamentResponse])
- async def list_filaments(
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_READ),
- ):
- """List all filaments."""
- result = await db.execute(select(Filament).order_by(Filament.type, Filament.name))
- return list(result.scalars().all())
- @router.post("/", response_model=FilamentResponse)
- async def create_filament(
- filament_data: FilamentCreate,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_CREATE),
- ):
- """Create a new filament entry."""
- filament = Filament(**filament_data.model_dump())
- db.add(filament)
- await db.commit()
- await db.refresh(filament)
- return filament
- @router.get("/{filament_id}", response_model=FilamentResponse)
- async def get_filament(
- filament_id: int,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_READ),
- ):
- """Get a specific filament."""
- result = await db.execute(select(Filament).where(Filament.id == filament_id))
- filament = result.scalar_one_or_none()
- if not filament:
- raise HTTPException(404, "Filament not found")
- return filament
- @router.patch("/{filament_id}", response_model=FilamentResponse)
- async def update_filament(
- filament_id: int,
- filament_data: FilamentUpdate,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_UPDATE),
- ):
- """Update a filament."""
- result = await db.execute(select(Filament).where(Filament.id == filament_id))
- filament = result.scalar_one_or_none()
- if not filament:
- raise HTTPException(404, "Filament not found")
- for field, value in filament_data.model_dump(exclude_unset=True).items():
- setattr(filament, field, value)
- await db.commit()
- await db.refresh(filament)
- return filament
- @router.delete("/{filament_id}")
- async def delete_filament(
- filament_id: int,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_DELETE),
- ):
- """Delete a filament."""
- result = await db.execute(select(Filament).where(Filament.id == filament_id))
- filament = result.scalar_one_or_none()
- if not filament:
- raise HTTPException(404, "Filament not found")
- await db.delete(filament)
- await db.commit()
- return {"status": "deleted"}
- @router.post("/calculate-cost", response_model=FilamentCostCalculation)
- async def calculate_cost(
- filament_id: int,
- weight_grams: float,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_READ),
- ):
- """Calculate the cost for a given weight of filament."""
- result = await db.execute(select(Filament).where(Filament.id == filament_id))
- filament = result.scalar_one_or_none()
- if not filament:
- raise HTTPException(404, "Filament not found")
- cost = (weight_grams / 1000) * filament.cost_per_kg
- return FilamentCostCalculation(
- filament_id=filament.id,
- filament_name=filament.name,
- weight_grams=weight_grams,
- cost=round(cost, 2),
- currency=filament.currency,
- )
- @router.get("/by-type/{filament_type}", response_model=list[FilamentResponse])
- async def get_filaments_by_type(
- filament_type: str,
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_READ),
- ):
- """Get all filaments of a specific type."""
- result = await db.execute(select(Filament).where(Filament.type.ilike(f"%{filament_type}%")).order_by(Filament.name))
- return list(result.scalars().all())
- @router.post("/seed-defaults")
- async def seed_default_filaments(
- db: AsyncSession = Depends(get_db),
- _: User | None = RequirePermissionIfAuthEnabled(Permission.FILAMENTS_CREATE),
- ):
- """Seed the database with common filament types."""
- defaults = [
- {
- "name": "Generic PLA",
- "type": "PLA",
- "cost_per_kg": 20.0,
- "print_temp_min": 190,
- "print_temp_max": 220,
- "bed_temp_min": 50,
- "bed_temp_max": 60,
- "density": 1.24,
- },
- {
- "name": "Generic PETG",
- "type": "PETG",
- "cost_per_kg": 25.0,
- "print_temp_min": 230,
- "print_temp_max": 250,
- "bed_temp_min": 70,
- "bed_temp_max": 80,
- "density": 1.27,
- },
- {
- "name": "Generic ABS",
- "type": "ABS",
- "cost_per_kg": 22.0,
- "print_temp_min": 230,
- "print_temp_max": 260,
- "bed_temp_min": 90,
- "bed_temp_max": 110,
- "density": 1.04,
- },
- {
- "name": "Generic TPU",
- "type": "TPU",
- "cost_per_kg": 35.0,
- "print_temp_min": 220,
- "print_temp_max": 250,
- "bed_temp_min": 40,
- "bed_temp_max": 60,
- "density": 1.21,
- },
- {
- "name": "Generic ASA",
- "type": "ASA",
- "cost_per_kg": 28.0,
- "print_temp_min": 240,
- "print_temp_max": 260,
- "bed_temp_min": 90,
- "bed_temp_max": 110,
- "density": 1.07,
- },
- {
- "name": "Bambu PLA Basic",
- "type": "PLA",
- "brand": "Bambu Lab",
- "cost_per_kg": 20.0,
- "print_temp_min": 190,
- "print_temp_max": 220,
- "bed_temp_min": 35,
- "bed_temp_max": 55,
- "density": 1.24,
- },
- {
- "name": "Bambu PLA Matte",
- "type": "PLA",
- "brand": "Bambu Lab",
- "cost_per_kg": 25.0,
- "print_temp_min": 190,
- "print_temp_max": 220,
- "bed_temp_min": 35,
- "bed_temp_max": 55,
- "density": 1.24,
- },
- {
- "name": "Bambu PETG Basic",
- "type": "PETG",
- "brand": "Bambu Lab",
- "cost_per_kg": 25.0,
- "print_temp_min": 250,
- "print_temp_max": 270,
- "bed_temp_min": 70,
- "bed_temp_max": 80,
- "density": 1.27,
- },
- {
- "name": "Bambu ABS",
- "type": "ABS",
- "brand": "Bambu Lab",
- "cost_per_kg": 30.0,
- "print_temp_min": 260,
- "print_temp_max": 280,
- "bed_temp_min": 90,
- "bed_temp_max": 100,
- "density": 1.04,
- },
- ]
- created = 0
- for filament_data in defaults:
- # Check if already exists
- result = await db.execute(
- select(Filament).where(
- Filament.name == filament_data["name"],
- Filament.type == filament_data["type"],
- )
- )
- if result.scalar_one_or_none():
- continue
- filament = Filament(**filament_data)
- db.add(filament)
- created += 1
- await db.commit()
- return {"created": created, "message": f"Created {created} default filaments"}
|