Set meal as purchased
This commit is contained in:
parent
571f187abd
commit
e06ad7611b
3 changed files with 48 additions and 10 deletions
11
main.py
11
main.py
|
|
@ -234,19 +234,19 @@ async def mark_consumed(meal_id: int, consumed_date: Optional[datetime.datetime]
|
||||||
return JSONResponse(status_code=404, content={'message': 'Meal not found'})
|
return JSONResponse(status_code=404, content={'message': 'Meal not found'})
|
||||||
|
|
||||||
await meals.mark_consumed(conn, meal, consumed_date or datetime.datetime.now().astimezone())
|
await meals.mark_consumed(conn, meal, consumed_date or datetime.datetime.now().astimezone())
|
||||||
await shopping.unrequest_meal(conn, meal)
|
await shopping.remove_request(conn, person, meal=meal)
|
||||||
|
|
||||||
await conn.commit()
|
await conn.commit()
|
||||||
return meal
|
return meal
|
||||||
|
|
||||||
@app.delete("/api/meals/{meal_id}")
|
@app.delete("/api/meals/{meal_id}")
|
||||||
async def delete_meal(meal_id: int, conn: sqlite3.Connection = Depends(get_db)) -> meals.Meal:
|
async def delete_meal(meal_id: int, conn: sqlite3.Connection = Depends(get_db), person: persons.Person = Depends(cookie_person)) -> meals.Meal:
|
||||||
meal = await meals.find_meal_by_id(conn, meal_id)
|
meal = await meals.find_meal_by_id(conn, meal_id)
|
||||||
if not meal:
|
if not meal:
|
||||||
return JSONResponse(status_code=404, content={'message': 'Meal not found'})
|
return JSONResponse(status_code=404, content={'message': 'Meal not found'})
|
||||||
|
|
||||||
|
await shopping.remove_request(conn, person, meal=meal)
|
||||||
await meals.delete_meal(conn, meal.id)
|
await meals.delete_meal(conn, meal.id)
|
||||||
await shopping.unrequest_meal(conn, meal)
|
|
||||||
|
|
||||||
await conn.commit()
|
await conn.commit()
|
||||||
return meal
|
return meal
|
||||||
|
|
@ -291,9 +291,8 @@ class PurchasedShoppingList(BaseModel):
|
||||||
@app.get("/api/shopping/{list_id}")
|
@app.get("/api/shopping/{list_id}")
|
||||||
async def get_shopping_list(list_id: int, conn: sqlite3.Connection = Depends(get_db)) -> PurchasedShoppingList:
|
async def get_shopping_list(list_id: int, conn: sqlite3.Connection = Depends(get_db)) -> PurchasedShoppingList:
|
||||||
shopping_list = await shopping.load_shopping_list(conn, list_id)
|
shopping_list = await shopping.load_shopping_list(conn, list_id)
|
||||||
result = PurchasedShoppingList(list=shopping_list)
|
meals_lookup, recipes_lookup, ingredients_lookup = shopping.remove_references(shopping_list.items)
|
||||||
shopping.remove_references(result.list.items, result.meals_lookup, result.recipes_lookup, result.ingredients_lookup)
|
return PurchasedShoppingList(list=shopping_list, meals_lookup=meals_lookup, recipes_lookup=recipes_lookup, ingredients_lookup=ingredients_lookup)
|
||||||
return result
|
|
||||||
|
|
||||||
@app.post("/api/shopping/")
|
@app.post("/api/shopping/")
|
||||||
async def purchase_ingredients(shopping_list: shopping.ShoppingList, conn: sqlite3.Connection = Depends(get_db), person: persons.Person = Depends(cookie_person)) -> PurchasedShoppingList:
|
async def purchase_ingredients(shopping_list: shopping.ShoppingList, conn: sqlite3.Connection = Depends(get_db), person: persons.Person = Depends(cookie_person)) -> PurchasedShoppingList:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ from shopping.db import ShoppingList, ShoppingListItem, load_shopping_list, purc
|
||||||
|
|
||||||
from shopping.db import find_items_by_list_id as _find_items_by_list_id, get_purchased_ingredients as _get_purchased_ingredients
|
from shopping.db import find_items_by_list_id as _find_items_by_list_id, get_purchased_ingredients as _get_purchased_ingredients
|
||||||
|
|
||||||
def remove_references(items: List[ShoppingListItem], meals_lookup = {}, recipes_lookup = {}, ingredients_lookup = {}) -> Tuple[Dict[int, Any], Dict[int, Any], Dict[int, Any]]:
|
def remove_references(items: List[ShoppingListItem], meals_lookup = None, recipes_lookup = None, ingredients_lookup = None) -> Tuple[Dict[int, Any], Dict[int, Any], Dict[int, Any]]:
|
||||||
|
meals_lookup = meals_lookup or {}
|
||||||
|
recipes_lookup = recipes_lookup or {}
|
||||||
|
ingredients_lookup = ingredients_lookup or {}
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
if item.meal and not item.meal.id in meals_lookup:
|
if item.meal and not item.meal.id in meals_lookup:
|
||||||
meals_lookup[item.meal.id] = item.meal
|
meals_lookup[item.meal.id] = item.meal
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from common import BaseLinkedModel
|
from common import BaseLinkedModel
|
||||||
from recipes import Recipe
|
from recipes import Recipe
|
||||||
from meals import Meal, find_meal_by_id
|
from meals import Meal, find_meal_by_id, mark_purchased
|
||||||
from ingredients import Ingredient, insert_ingredient
|
from ingredients import Ingredient, insert_ingredient
|
||||||
from persons import Person
|
from persons import Person
|
||||||
from products import Product
|
from products import Product
|
||||||
|
|
@ -71,7 +71,6 @@ async def create(conn):
|
||||||
FOREIGN KEY(recipe_id) REFERENCES Recipe(id)
|
FOREIGN KEY(recipe_id) REFERENCES Recipe(id)
|
||||||
);''')
|
);''')
|
||||||
|
|
||||||
|
|
||||||
def validate_request(request: ShoppingListItem) -> None:
|
def validate_request(request: ShoppingListItem) -> None:
|
||||||
if request.person_id < 0:
|
if request.person_id < 0:
|
||||||
raise ValueError('Requests must have a person')
|
raise ValueError('Requests must have a person')
|
||||||
|
|
@ -139,7 +138,40 @@ async def purchase(conn, shopping_list: ShoppingList) -> None:
|
||||||
''', (item.ingredient_id, shopping_list.id, item.person_id, item.meal_id, item.recipe_id, item.created_date.isoformat())) as cursor:
|
''', (item.ingredient_id, shopping_list.id, item.person_id, item.meal_id, item.recipe_id, item.created_date.isoformat())) as cursor:
|
||||||
item.id = cursor.lastrowid
|
item.id = cursor.lastrowid
|
||||||
|
|
||||||
# TODO: Calculate which meals have been fulfilled and update meal status
|
meal_ids = list({ item.meal_id for item in shopping_list.items if item.meal_id is not None and item.meal_id >= 0 })
|
||||||
|
await update_purchased_meals(conn, meal_ids)
|
||||||
|
|
||||||
|
async def update_purchased_meals(conn, meal_ids: List[int]) -> None:
|
||||||
|
if not meal_ids:
|
||||||
|
return
|
||||||
|
|
||||||
|
purchased_ingredient_ids = {item.ingredient_id async for item in get_purchased_ingredients(conn, meal_ids)}
|
||||||
|
for meal_id in meal_ids:
|
||||||
|
meal = await find_meal_by_id(conn, meal_id)
|
||||||
|
ingredients = {ingredient.id for recipe in meal.recipes for ingredient in recipe.recipe.ingredients} | \
|
||||||
|
{ingredient.id for ingredient in meal.extra_ingredients}
|
||||||
|
|
||||||
|
remaining_ingredients = ingredients - purchased_ingredient_ids
|
||||||
|
if not remaining_ingredients:
|
||||||
|
await mark_purchased(conn, meal)
|
||||||
|
|
||||||
|
# If all ingredients are purchased, update the meal status
|
||||||
|
await conn.execute('''
|
||||||
|
UPDATE Meal
|
||||||
|
SET purchase_date = ?
|
||||||
|
WHERE id = ?
|
||||||
|
''', (datetime.now().isoformat(), meal.id))
|
||||||
|
|
||||||
|
async def is_requested(conn, meal: Meal) -> bool:
|
||||||
|
if meal.id < 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
async with conn.execute('''
|
||||||
|
SELECT COUNT(*) FROM ShoppingListItem
|
||||||
|
WHERE meal_id = ? AND list_id IS NULL
|
||||||
|
''', (meal.id,)) as cursor:
|
||||||
|
row = await cursor.fetchone()
|
||||||
|
return row[0] > 0
|
||||||
|
|
||||||
async def request(conn, person: Person, ingredient: Optional[Ingredient] = None, meal: Optional[Meal] = None) -> ShoppingListItem:
|
async def request(conn, person: Person, ingredient: Optional[Ingredient] = None, meal: Optional[Meal] = None) -> ShoppingListItem:
|
||||||
if ingredient is not None and meal is not None:
|
if ingredient is not None and meal is not None:
|
||||||
|
|
@ -158,6 +190,9 @@ async def request(conn, person: Person, ingredient: Optional[Ingredient] = None,
|
||||||
|
|
||||||
validate_request(item)
|
validate_request(item)
|
||||||
|
|
||||||
|
if meal is not None and await is_requested(conn, meal):
|
||||||
|
raise ValueError('Meal is already requested')
|
||||||
|
|
||||||
async with conn.execute('''
|
async with conn.execute('''
|
||||||
INSERT INTO ShoppingListItem (ingredient_id, person_id, meal_id, created_date)
|
INSERT INTO ShoppingListItem (ingredient_id, person_id, meal_id, created_date)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue