summaryrefslogtreecommitdiff
path: root/kitchen/helpers.py
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"