diff --git a/ingredients/db.py b/ingredients/db.py index 2d38af7..b10dad1 100644 --- a/ingredients/db.py +++ b/ingredients/db.py @@ -38,7 +38,7 @@ async def insert_ingredient(conn, ingredient: Ingredient): ingredient.product_id = ingredient.product.id if ingredient.product_id < 0: - raise ValueError('Product must be inserted before ingredient') + ingredient.product_id = None async with conn.execute(''' INSERT INTO Ingredient (name, line, preparation, unit, quantity, product_id, recipe_id, meal_id) diff --git a/main.py b/main.py index bb86610..f94cf04 100644 --- a/main.py +++ b/main.py @@ -109,10 +109,6 @@ async def create_recipe(recipe: recipes.Recipe, conn: sqlite3.Connection = Depen if not recipe.ingredients: return JSONResponse(status_code=400, content={'message': 'Recipe must have at least one ingredient'}) - for ingredient in recipe.ingredients: - if not ingredient.product: - return JSONResponse(status_code=400, content={'message': 'Ingredient must have a product'}) - if recipe.id >= 0: await recipes.hide_recipe(conn, recipe.id, user) recipe.based_on_recipe = recipe.id @@ -122,7 +118,9 @@ async def create_recipe(recipe: recipes.Recipe, conn: sqlite3.Connection = Depen await recipes.insert_recipe(conn, recipe) for ingredient in recipe.ingredients: ingredient.recipe_id = recipe.id - ingredient.product_id = ingredient.product.id + if ingredient.product: + ingredient.product_id = ingredient.product.id + await ingredients.insert_ingredient(conn, ingredient) await conn.commit() @@ -275,20 +273,9 @@ async def get_current_shopping_list(conn: sqlite3.Connection = Depends(get_db)) async def get_shopping_list(list_id: int, conn: sqlite3.Connection = Depends(get_db)) -> shopping.ShoppingList: return await shopping.load_shopping_list(conn, list_id) -class ShoppingListPurchase(shopping.ShoppingList): - completed_requests: List[shopping.ShoppingListRequest] = [] - @app.post("/api/shopping/") -async def purchase_ingredients(lst: ShoppingListPurchase, conn: sqlite3.Connection = Depends(get_db)) -> shopping.ShoppingList: - await shopping.insert_shopping_list(conn, lst) - for request in lst.completed_requests: - if request.meal_id: - meal = await meals.find_meal_by_id(conn, request.meal_id) - if meal: - await meals.mark_purchased(conn, meal) - - await shopping.remove_request(conn, request) - +async def purchase_ingredients(lst: shopping.ShoppingListPurchase, conn: sqlite3.Connection = Depends(get_db)) -> shopping.ShoppingList: + await shopping.purchase_ingredients(conn, lst) await conn.commit() return lst diff --git a/shopping/__init__.py b/shopping/__init__.py index e7e75b8..a569739 100644 --- a/shopping/__init__.py +++ b/shopping/__init__.py @@ -1,2 +1,2 @@ -from shopping.db import ShoppingList, ShoppingListRequest, ShoppingListResult, sync_persons_requested_ingredients, load_shopping_list, get_current_requests, request_meal, unrequest_meal, insert_shopping_list, get_shopping_list_with_meal, remove_request +from shopping.db import ShoppingList, ShoppingListRequest, ShoppingListResult, ShoppingListPurchase, sync_persons_requested_ingredients, load_shopping_list, get_current_requests, request_meal, unrequest_meal, purchase_ingredients, get_shopping_list_with_meal, remove_request diff --git a/shopping/db.py b/shopping/db.py index 2a7163a..e4207aa 100644 --- a/shopping/db.py +++ b/shopping/db.py @@ -50,6 +50,9 @@ class ShoppingList(BaseModel): requests: List[ShoppingListRequest] = [] results: List[ShoppingListResult] = [] +class ShoppingListPurchase(ShoppingList): + completed_requests: List[ShoppingListRequest] = [] + async def create(conn): await conn.execute(''' CREATE TABLE IF NOT EXISTS ShoppingList ( @@ -92,14 +95,11 @@ def validate_request(request: ShoppingListRequest) -> None: if not request.ingredient and not request.meal: raise ValueError('Request must have either an ingredient or a meal') - if request.ingredient and request.meal: - raise ValueError('Request cannot have both an ingredient and a meal') - # If an ingredient is provided, it must have a person if request.ingredient and not request.person: raise ValueError('Ingredient requests must have a person') -async def insert_shopping_list(conn, shopping_list: ShoppingList): +async def purchase_ingredients(conn, shopping_list: ShoppingListPurchase): shopping_list.created_date = datetime.now().astimezone() async with conn.execute(''' @@ -108,7 +108,7 @@ async def insert_shopping_list(conn, shopping_list: ShoppingList): ''', (shopping_list.created_date.isoformat(), shopping_list.store_name,)) as cursor: shopping_list.id = cursor.lastrowid - for request in shopping_list.requests: + for request in shopping_list.completed_requests: request.list_id = shopping_list.id validate_request(request) @@ -128,15 +128,21 @@ async def insert_shopping_list(conn, shopping_list: ShoppingList): ''', (request.ingredient_id, shopping_list.id, request.person_id, request.meal_id, request.created_date.isoformat())) as cursor: request.id = cursor.lastrowid - for item in shopping_list.results: - item.product_id = item.product.id - item.list_id = shopping_list.id + if request.ingredient_id and request.person_id: + await conn.execute(''' + DELETE FROM ShoppingListRequest + WHERE ingredient_id = ? AND person_id = ? AND list_id IS NULL + ''', (request.ingredient_id, request.person_id)) + +from meals import find_meal_by_id +async def find_completed_meals(conn, shopping_list_request: List[ShoppingListRequest]) -> AsyncIterator[Meal]: + meal_ids = {request.meal_id for request in shopping_list_request if request.meal_id is not None} + if not meal_ids: + return + + meals = [await find_meal_by_id(conn, meal_id) for meal_id in meal_ids] + ingredients_as_requests = [ShoppingListRequest(meal_id=meal.id, meal=meal, list_id=shopping_list_request[0].list_id) for meal in meals] - async with conn.execute(''' - INSERT INTO ShoppingListResult (product_id, list_id, quantity, unit) - VALUES (?, ?, ?, ?) - ''', (item.product_id, item.list_id, item.quantity, item.unit)) as cursor: - item.id = cursor.lastrowid async def remove_request(conn, request: ShoppingListRequest) -> None: if request.list_id != None: