summaryrefslogtreecommitdiff
path: root/routers/pantry.py
diff options
context:
space:
mode:
Diffstat (limited to 'routers/pantry.py')
-rw-r--r--routers/pantry.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/routers/pantry.py b/routers/pantry.py
new file mode 100644
index 0000000..d6638f8
--- /dev/null
+++ b/routers/pantry.py
@@ -0,0 +1,101 @@
+from fastapi import APIRouter, Depends, HTTPException, Query, status
+from sqlalchemy.orm import Session
+from datetime import datetime, timedelta
+from typing import List
+
+from database import get_db
+from models import Ingredient
+from schemas import IngredientCreate, IngredientRead, IngredientUpdate
+
+router = APIRouter(prefix="/api/pantry", tags=["pantry"])
+
+
+@router.get("", response_model=List[IngredientRead])
+def list_ingredients(
+ expiring_soon: bool = Query(False),
+ db: Session = Depends(get_db)
+):
+ """List all ingredients. Optional query param ?expiring_soon=true filters to ingredients with expiry_date within 7 days from today."""
+ query = db.query(Ingredient)
+
+ if expiring_soon:
+ today = datetime.utcnow().date()
+ seven_days_later = today + timedelta(days=7)
+ query = query.filter(
+ (Ingredient.expiry_date >= today) & (Ingredient.expiry_date <= seven_days_later)
+ )
+
+ return query.all()
+
+
+@router.get("/expiring", response_model=List[IngredientRead])
+def list_expiring_ingredients(db: Session = Depends(get_db)):
+ """Ingredients expiring within 7 days."""
+ today = datetime.utcnow().date()
+ seven_days_later = today + timedelta(days=7)
+
+ return db.query(Ingredient).filter(
+ (Ingredient.expiry_date >= today) & (Ingredient.expiry_date <= seven_days_later)
+ ).all()
+
+
+@router.post("", response_model=IngredientRead, status_code=status.HTTP_201_CREATED)
+def create_ingredient(ingredient: IngredientCreate, db: Session = Depends(get_db)):
+ """Create a new ingredient."""
+ db_ingredient = Ingredient(**ingredient.model_dump())
+ db.add(db_ingredient)
+ db.commit()
+ db.refresh(db_ingredient)
+ return db_ingredient
+
+
+@router.put("/{id}", response_model=IngredientRead)
+def update_ingredient(id: int, ingredient: IngredientUpdate, db: Session = Depends(get_db)):
+ """Update ingredient fields (partial update)."""
+ db_ingredient = db.query(Ingredient).filter(Ingredient.id == id).first()
+ if not db_ingredient:
+ raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ingredient not found")
+
+ update_data = ingredient.model_dump(exclude_unset=True)
+ for field, value in update_data.items():
+ setattr(db_ingredient, field, value)
+
+ db_ingredient.updated_at = datetime.utcnow()
+ db.commit()
+ db.refresh(db_ingredient)
+ return db_ingredient
+
+
+@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
+def delete_ingredient(id: int, db: Session = Depends(get_db)):
+ """Delete an ingredient."""
+ db_ingredient = db.query(Ingredient).filter(Ingredient.id == id).first()
+ if not db_ingredient:
+ raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ingredient not found")
+
+ db.delete(db_ingredient)
+ db.commit()
+
+
+@router.post("/bulk", response_model=List[IngredientRead])
+def bulk_upsert_ingredients(ingredients: List[IngredientCreate], db: Session = Depends(get_db)):
+ """Upsert list of ingredients. If an ingredient with same name exists, add the quantity (accumulate). If not, create new."""
+ result = []
+
+ for ingredient_data in ingredients:
+ existing = db.query(Ingredient).filter(Ingredient.name == ingredient_data.name).first()
+
+ if existing:
+ existing.quantity += ingredient_data.quantity
+ existing.updated_at = datetime.utcnow()
+ db.commit()
+ db.refresh(existing)
+ result.append(existing)
+ else:
+ new_ingredient = Ingredient(**ingredient_data.model_dump())
+ db.add(new_ingredient)
+ db.commit()
+ db.refresh(new_ingredient)
+ result.append(new_ingredient)
+
+ return result