related recipes included when adding mealplan to shopping list

This commit is contained in:
smilerz
2021-10-28 20:40:56 -05:00
parent 27f358dd03
commit 8b682c33f3
13 changed files with 519 additions and 594 deletions

View File

@ -1,3 +1,4 @@
from decimal import Decimal
from functools import wraps
from django.contrib.postgres.search import SearchVector
@ -5,8 +6,10 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import translation
from cookbook.helper.shopping_helper import list_from_recipe
from cookbook.managers import DICTIONARY
from cookbook.models import Food, FoodInheritField, Recipe, Step
from cookbook.models import (Food, FoodInheritField, Ingredient, MealPlan, Recipe,
ShoppingListEntry, Step)
# wraps a signal with the ability to set 'skip_signal' to avoid creating recursive signals
@ -78,3 +81,52 @@ def update_food_inheritance(sender, instance=None, created=False, **kwargs):
# don't cascade empty supermarket category
if instance.supermarket_category:
instance.get_children().filter(inherit=True).exclude(ignore_inherit__field='supermarket_category').update(supermarket_category=instance.supermarket_category)
@receiver(post_save, sender=MealPlan)
def auto_add_shopping(sender, instance=None, created=False, weak=False, **kwargs):
user = instance.get_owner()
if not created or not user.userpreference.mealplan_autoadd_shopping:
return
# if creating a mealplan - perform shopping list activities
space = instance.space
if user.userpreference.mealplan_autoadd_shopping:
kwargs = {
'mealplan': instance,
'space': space,
'created_by': user,
'servings': instance.servings
}
recipe_ingredients = Ingredient.objects.filter(step__recipe=instance.recipe, space=space)
if exclude_onhand := user.userpreference.mealplan_autoexclude_onhand:
recipe_ingredients = recipe_ingredients.exclude(food__on_hand=True)
if related := user.userpreference.mealplan_autoinclude_related:
# TODO: add levels of related recipes to use when auto-adding mealplans
related_recipes = instance.recipe.get_related_recipes()
# dont' add recipes that are going to have their recipes added to the shopping list
kwargs['ingredients'] = recipe_ingredients.exclude(food__recipe__in=related_recipes).values_list('id', flat=True)
else:
kwargs['ingredients'] = recipe_ingredients.values_list('id', flat=True)
list_recipe = list_from_recipe(**kwargs)
if related:
servings_factor = Decimal(instance.servings / instance.recipe.servings)
kwargs['list_recipe'] = list_recipe
food_recipes = recipe_ingredients.filter(food__recipe__in=related_recipes).values('food__recipe', 'amount')
for recipe in related_recipes:
kwargs['ingredients'] = []
if exclude_onhand:
kwargs['ingredients'] = Ingredient.objects.filter(step__recipe=recipe, food__on_hand=False, space=space).values_list('id', flat=True)
kwargs['recipe'] = recipe
# assume related recipes are intended to be 'full sized' to parent recipe
# Recipe1 (servings:4) includes StepRecipe2(servings:2) a Meal Plan serving size of 8 would assume 4 servings of StepRecipe2
if recipe.id in [x['food__recipe'] for x in food_recipes if x['food__recipe'] == recipe.id]:
kwargs['servings'] = Decimal(recipe.servings) * sum([x['amount'] for x in food_recipes if x['food__recipe'] == recipe.id]) * servings_factor
else:
# TODO: When modifying step recipes to allow serving size - will need to update this
kwargs['servings'] = Decimal(recipe.servings) * servings_factor
list_from_recipe(**kwargs, append=True)