v1.2 scaffold
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db.session import get_db
|
||||
from app.models.mix import Mix, MixIngredient
|
||||
from app.models.raw_material import RawMaterial
|
||||
from app.schemas.mix import MixCreate, MixIngredientCreate, MixIngredientUpdate, MixRead, MixUpdate
|
||||
from app.services.costing_engine import calculate_mix_cost
|
||||
|
||||
router = APIRouter(prefix="/api/mixes", tags=["mixes"])
|
||||
|
||||
|
||||
@router.get("", response_model=list[MixRead])
|
||||
def list_mixes(db: Session = Depends(get_db)):
|
||||
mixes = db.scalars(select(Mix).order_by(Mix.name)).all()
|
||||
return [calculate_mix_cost(db, mix.id) for mix in mixes]
|
||||
|
||||
|
||||
@router.post("", response_model=MixRead, status_code=status.HTTP_201_CREATED)
|
||||
def create_mix(payload: MixCreate, db: Session = Depends(get_db)):
|
||||
mix = Mix(
|
||||
client_name=payload.client_name,
|
||||
name=payload.name,
|
||||
status=payload.status,
|
||||
version=payload.version,
|
||||
notes=payload.notes,
|
||||
)
|
||||
db.add(mix)
|
||||
db.flush()
|
||||
for ingredient in payload.ingredients:
|
||||
if db.scalar(select(RawMaterial).where(RawMaterial.id == ingredient.raw_material_id)) is None:
|
||||
raise HTTPException(status_code=404, detail=f"Raw material {ingredient.raw_material_id} not found")
|
||||
db.add(
|
||||
MixIngredient(
|
||||
mix_id=mix.id,
|
||||
raw_material_id=ingredient.raw_material_id,
|
||||
quantity_kg=ingredient.quantity_kg,
|
||||
notes=ingredient.notes,
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
return calculate_mix_cost(db, mix.id)
|
||||
|
||||
|
||||
@router.get("/{mix_id}", response_model=MixRead)
|
||||
def get_mix(mix_id: int, db: Session = Depends(get_db)):
|
||||
if db.scalar(select(Mix.id).where(Mix.id == mix_id)) is None:
|
||||
raise HTTPException(status_code=404, detail="Mix not found")
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
|
||||
@router.patch("/{mix_id}", response_model=MixRead)
|
||||
def update_mix(mix_id: int, payload: MixUpdate, db: Session = Depends(get_db)):
|
||||
mix = db.scalar(select(Mix).where(Mix.id == mix_id))
|
||||
if mix is None:
|
||||
raise HTTPException(status_code=404, detail="Mix not found")
|
||||
for field, value in payload.model_dump(exclude_unset=True).items():
|
||||
setattr(mix, field, value)
|
||||
db.commit()
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
|
||||
@router.post("/{mix_id}/ingredients", response_model=MixRead, status_code=status.HTTP_201_CREATED)
|
||||
def add_mix_ingredient(mix_id: int, payload: MixIngredientCreate, db: Session = Depends(get_db)):
|
||||
if db.scalar(select(Mix.id).where(Mix.id == mix_id)) is None:
|
||||
raise HTTPException(status_code=404, detail="Mix not found")
|
||||
if db.scalar(select(RawMaterial.id).where(RawMaterial.id == payload.raw_material_id)) is None:
|
||||
raise HTTPException(status_code=404, detail="Raw material not found")
|
||||
db.add(MixIngredient(mix_id=mix_id, raw_material_id=payload.raw_material_id, quantity_kg=payload.quantity_kg, notes=payload.notes))
|
||||
db.commit()
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
|
||||
@router.patch("/{mix_id}/ingredients/{ingredient_id}", response_model=MixRead)
|
||||
def update_mix_ingredient(mix_id: int, ingredient_id: int, payload: MixIngredientUpdate, db: Session = Depends(get_db)):
|
||||
ingredient = db.scalar(select(MixIngredient).where(MixIngredient.id == ingredient_id, MixIngredient.mix_id == mix_id))
|
||||
if ingredient is None:
|
||||
raise HTTPException(status_code=404, detail="Ingredient not found")
|
||||
for field, value in payload.model_dump(exclude_unset=True).items():
|
||||
setattr(ingredient, field, value)
|
||||
db.commit()
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
|
||||
@router.delete("/{mix_id}/ingredients/{ingredient_id}", response_model=MixRead)
|
||||
def delete_mix_ingredient(mix_id: int, ingredient_id: int, db: Session = Depends(get_db)):
|
||||
ingredient = db.scalar(select(MixIngredient).where(MixIngredient.id == ingredient_id, MixIngredient.mix_id == mix_id))
|
||||
if ingredient is None:
|
||||
raise HTTPException(status_code=404, detail="Ingredient not found")
|
||||
db.delete(ingredient)
|
||||
db.commit()
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
|
||||
@router.get("/{mix_id}/cost-breakdown", response_model=MixRead)
|
||||
def get_mix_cost_breakdown(mix_id: int, db: Session = Depends(get_db)):
|
||||
if db.scalar(select(Mix.id).where(Mix.id == mix_id)) is None:
|
||||
raise HTTPException(status_code=404, detail="Mix not found")
|
||||
return calculate_mix_cost(db, mix_id)
|
||||
|
||||
Reference in New Issue
Block a user