blob: 7853fd7abdeab9d6fb274a3c5b67c829d7f17803 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
"""
Shared kitchen helpers used by both the DRF API views (views.py) and the
HTMX views (views_htmx.py). Consolidated here to avoid cross-module
duplication and the views_htmx -> views runtime coupling.
"""
from decimal import Decimal
from .models import Ingredient, PantryItem
def find_ingredient(name):
"""Find ingredient by name or alias (case-insensitive)."""
# Exact name match
try:
return Ingredient.objects.get(name__iexact=name)
except Ingredient.DoesNotExist:
pass
# Search aliases (JSONField contains). Guard against a falsy aliases value.
for ingredient in Ingredient.objects.all():
if ingredient.aliases and any(a.lower() == name.lower() for a in ingredient.aliases):
return ingredient
return None
def get_pantry_total(ingredient_id):
"""Total quantity of an ingredient across all locations, excluding items
marked 'out'. Null quantities count as 0 (presence is tracked via state,
not this number — see the pantry redesign in plan.md)."""
total = Decimal("0")
for item in (
PantryItem.objects.filter(ingredient_id=ingredient_id)
.exclude(state=PantryItem.State.OUT)
):
total += Decimal(item.quantity or 0)
return total
def get_section_key(ingredient):
"""Determine the canonical (lowercase) shopping section key from an
ingredient's tags."""
tag_names = set(ingredient.tags.values_list("name", flat=True))
if "protein" in tag_names:
return "protein"
if "veg" in tag_names:
return "veg"
if "carb" in tag_names:
return "carbs"
if "dairy" in tag_names:
return "dairy"
return "other"
|