from typing import AsyncIterator, Iterator, List, Tuple from shopping.db import ShoppingList, ShoppingListItem, load_shopping_list, purchase, remove_request, request from shopping.db import find_items_by_list_id as _find_items_by_list_id, get_purchased_ingredients as _get_purchased_ingredients async def get_persons_requests(conn, person_id: int) -> AsyncIterator[ShoppingListItem]: async for item in _find_items_by_list_id(conn, None): if item.person_id == person_id and item.ingredient_id is not None: yield item def flatten_items(items: Iterator[ShoppingListItem]) -> Iterator[ShoppingListItem]: for item in items: if item.meal: for mealRecipe in item.meal.recipes: for ingredient in mealRecipe.recipe.ingredients: yield ShoppingListItem(ingredient=ingredient, meal=item.meal, recipe=mealRecipe.recipe, person_id=item.person_id, created_date=item.created_date) for ingredient in item.meal.extra_ingredients: yield ShoppingListItem(ingredient=ingredient, meal=item.meal, person_id=item.person_id, created_date=item.created_date) else: yield item async def get_outstanding_requests(conn) -> Tuple[List[ShoppingListItem], List[ShoppingListItem], List[ShoppingListItem]]: current_requests = [r async for r in _find_items_by_list_id(conn, None)] meal_requests = [r for r in current_requests if r.meal_id is not None and r.meal_id > 0 and r.meal is not None] meals = {r.meal_id: r.meal for r in meal_requests} purchased_ingredients = {r.ingredient_id async for r in _get_purchased_ingredients(conn, list(meals.keys()))} flattened = flatten_items(current_requests) outstanding_items = [r for r in flattened if r.ingredient_id not in purchased_ingredients] purchased_items = [r for r in flattened if r.ingredient_id in purchased_ingredients] return outstanding_items, purchased_items, meal_requests