diff --git a/.gitignore b/.gitignore index 0c9c2630a..7f8c9fb1a 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,3 @@ cookbook/static/vue vue/webpack-stats.json cookbook/templates/sw.js .prettierignore -vue/tsconfig.json diff --git a/cookbook/helper/shopping_helper.py b/cookbook/helper/shopping_helper.py index 1c51ec6d5..541fcb4f4 100644 --- a/cookbook/helper/shopping_helper.py +++ b/cookbook/helper/shopping_helper.py @@ -85,12 +85,12 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None ingredients = ingredients.exclude(food__on_hand=True) if related := created_by.userpreference.mealplan_autoinclude_related: - # TODO: add levels of related recipes to use when auto-adding mealplans + # TODO: add levels of related recipes (related recipes of related recipes) to use when auto-adding mealplans related_recipes = r.get_related_recipes() for x in related_recipes: # related recipe is a Step serving size is driven by recipe serving size - # TODO once Steps can have a serving size this needs to be refactored + # TODO once/if Steps can have a serving size this needs to be refactored if exclude_onhand: # if steps are used more than once in a recipe or subrecipe - I don' think this results in the desired behavior related_step_ing += Ingredient.objects.filter(step__recipe=x, food__on_hand=False, space=space).values_list('id', flat=True) diff --git a/cookbook/models.py b/cookbook/models.py index c55d95b47..729f02751 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -491,11 +491,11 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin): name = models.CharField(max_length=128, validators=[MinLengthValidator(1)]) recipe = models.ForeignKey('Recipe', null=True, blank=True, on_delete=models.SET_NULL) supermarket_category = models.ForeignKey(SupermarketCategory, null=True, blank=True, on_delete=models.SET_NULL) - ignore_shopping = models.BooleanField(default=False) + ignore_shopping = models.BooleanField(default=False) # inherited field description = models.TextField(default='', blank=True) on_hand = models.BooleanField(default=False) inherit = models.BooleanField(default=False) - ignore_inherit = models.ManyToManyField(FoodInheritField, blank=True) # is this better as inherit instead of ignore inherit? which is more intuitive? + ignore_inherit = models.ManyToManyField(FoodInheritField, blank=True) # inherited field: is this name better as inherit instead of ignore inherit? which is more intuitive? space = models.ForeignKey(Space, on_delete=models.CASCADE) objects = ScopedManager(space='space', _manager_class=TreeManager) @@ -511,6 +511,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin): @staticmethod def reset_inheritance(space=None): + # resets inheritted fields to the space defaults and updates all inheritted fields to root object values inherit = space.food_inherit.all() ignore_inherit = Food.inherit_fields.difference(inherit) diff --git a/cookbook/templates/shopping_list.html b/cookbook/templates/shopping_list.html index 9a3e05fbf..837c0eac8 100644 --- a/cookbook/templates/shopping_list.html +++ b/cookbook/templates/shopping_list.html @@ -355,7 +355,7 @@ {% else %} edit_mode: false, {% endif %} - export_text_prefix: '', //TODO add userpreference + export_text_prefix: '', recipe_query: '', recipes: [], shopping_list: undefined, diff --git a/cookbook/tests/api/test_api_food.py b/cookbook/tests/api/test_api_food.py index 107506bdb..0adf1ada4 100644 --- a/cookbook/tests/api/test_api_food.py +++ b/cookbook/tests/api/test_api_food.py @@ -526,4 +526,24 @@ def test_ignoreinherit_field(request, obj_tree_1, field, inherit, new_val, u1_s1 assert getattr(child, field) == new_val -# TODO test reset_inheritance +@pytest.mark.parametrize("obj_tree_1", [ + ({'has_category': True, 'inherit': False, 'ignore_shopping': True}), +], indirect=['obj_tree_1']) +def test_reset_inherit(obj_tree_1, space_1): + with scope(space=space_1): + space_1.food_inherit.add(*Food.inherit_fields.values_list('id', flat=True)) # set default inherit fields + parent = obj_tree_1.get_parent() + child = obj_tree_1.get_descendants()[0] + obj_tree_1.ignore_shopping = False + assert parent.ignore_shopping == child.ignore_shopping + assert parent.ignore_shopping != obj_tree_1.ignore_shopping + assert parent.supermarket_category != child.supermarket_category + assert parent.supermarket_category != obj_tree_1.supermarket_category + + parent.reset_inheritance(space=space_1) + # djangotree bypasses ORM and need to be retrieved again + obj_tree_1 = Food.objects.get(id=obj_tree_1.id) + parent = obj_tree_1.get_parent() + child = obj_tree_1.get_descendants()[0] + assert parent.ignore_shopping == obj_tree_1.ignore_shopping == child.ignore_shopping + assert parent.supermarket_category == obj_tree_1.supermarket_category == child.supermarket_category diff --git a/cookbook/tests/api/test_api_shopping_recipe.py b/cookbook/tests/api/test_api_shopping_recipe.py index f3f49b073..5b137fed0 100644 --- a/cookbook/tests/api/test_api_shopping_recipe.py +++ b/cookbook/tests/api/test_api_shopping_recipe.py @@ -222,7 +222,3 @@ def test_shopping_recipe_mixed_authors(u1_s1, u2_s1): u1_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe1.id})) assert len(json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)) == 29 assert len(json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)) == 0 - - -# TODO test creating shopping list from recipe that includes recipes from multiple users -# TODO meal plan recipe with all the user preferences tested