Skip to content

Commit

Permalink
Add test skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkjellid committed Jun 13, 2024
1 parent a24c0c3 commit 7e575f4
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 32 deletions.
15 changes: 10 additions & 5 deletions nest/recipes/plans/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from nest.core.exceptions import ApplicationError
from nest.recipes.core.records import RecipeDetailRecord
from nest.units.utils import convert_unit_quantity


class RecipeScoreData(TypedDict, total=True):
Expand Down Expand Up @@ -46,9 +47,15 @@ def _get_products_dataframe(self) -> pl.DataFrame:
for item in group.ingredient_items:
product = item.ingredient.product

if product.unit_quantity is None:
converted_quantity = convert_unit_quantity(
quantity=item.portion_quantity,
from_unit=item.portion_quantity_unit,
to_unit=product.unit,
)

if converted_quantity is None or product.unit_quantity is None:
raise ApplicationError(
"Product is missing unit quantity, impossible to "
"Recipe or product is missing quantity, impossible to "
"calculate required quantity without it",
extra={"product_id": product.id},
)
Expand All @@ -62,9 +69,7 @@ def _get_products_dataframe(self) -> pl.DataFrame:
"unit_abbreviation": product.unit.abbreviation,
"portion_quantity": item.portion_quantity,
"portion_quantity_unit_abbr": item.portion_quantity_unit.abbreviation,
"required_amount": (
item.portion_quantity / product.unit_quantity
),
"required_amount": converted_quantity / product.unit_quantity,
}
product_data.append(data)

Expand Down
10 changes: 5 additions & 5 deletions nest/recipes/plans/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@
RECIPE_GRACE_PERIOD_WEEKS = 2


def find_recipes_applicable_for_plan(plan_id: int) -> list[RecipeDetailRecord]:
first_possible_from_date = timezone.now() - timedelta(
weeks=RECIPE_GRACE_PERIOD_WEEKS
)
def find_recipes_applicable_for_plan(
*, grace_period_weeks: int = RECIPE_GRACE_PERIOD_WEEKS
) -> list[RecipeDetailRecord]:
first_possible_from_date = timezone.now() - timedelta(weeks=grace_period_weeks)
recipes = (
Recipe.objects.exclude(
plan_items__recipe_plan_id=plan_id,
plan_items__recipe_plan__from_date__lte=first_possible_from_date,
)
.filter(
status=RecipeStatus.PUBLISHED,
)
# TODO: Necessary? Should this rather be weighted in the algo?
.annotate(num_plan_usages=Count("plan_items"))
.annotate_duration()
.order_by("-num_plan_usages")
Expand Down
54 changes: 32 additions & 22 deletions nest/recipes/plans/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
from django.db import transaction
from django.utils.text import slugify

from nest.recipes.core.records import RecipeRecord
from nest.homes.records import HomeRecord
from nest.recipes.core.records import RecipeRecord, RecipeDetailRecord
from nest.recipes.plans.algorithm import PlanDistributor
from nest.recipes.plans.models import RecipePlan, RecipePlanItem
from nest.recipes.plans.selectors import find_recipes_applicable_for_plan


def create_weekly_recipe_plan(
*, from_date: date, num_items: int = 7, auto_generated: bool = False
def create_weekly_recipe_plan_for_home(
*,
home: HomeRecord,
from_date: date,
auto_generated: bool = False,
):
num_items = 7
week_number = from_date.isocalendar().week
to_date = from_date + timedelta(days=num_items)
title = f"Weekly plan {week_number} ({from_date} - {to_date}"
Expand All @@ -23,10 +29,13 @@ def create_weekly_recipe_plan(
)

create_recipe_plan(
home=home,
title=title,
description=description,
from_date=from_date,
budget=home.weekly_budget,
num_items=num_items,
grace_period_weeks=home.num_weeks_recipe_rotation,
)


Expand All @@ -36,10 +45,11 @@ def create_recipe_plan(
title: str,
description: str | None = None,
from_date: date,
budget: Decimal,
num_items: int,
num_pescatarian: int,
num_vegetarian: int,
monetary_cap: Decimal,
grace_period_weeks: int | None = None,
):
plan_slug = slugify(title)
recipe_plan = RecipePlan.objects.create(
Expand All @@ -49,34 +59,36 @@ def create_recipe_plan(
from_date=from_date,
)

applicable_recipes = find_recipes_applicable_for_plan(
grace_period_weeks=grace_period_weeks
)
plan_distributor = PlanDistributor(
budget=budget,
total_num_recipes=num_items,
num_pescatarian=num_pescatarian,
num_vegetarian=num_vegetarian,
applicable_recipes=applicable_recipes,
)

recipes_for_plan = plan_distributor.create_plan()

transaction.on_commit(
functools.partial(
_create_recipe_plan_items,
plan_id=recipe_plan.od,
plan_id=recipe_plan.id,
recipes=recipes_for_plan,
)
)


def _create_recipe_plan_items(plan_id: int) -> None:
def _create_recipe_plan_items(
*, plan_id: int, recipes: list[RecipeDetailRecord]
) -> None:
plan_items_to_create: list[RecipePlanItem] = []
ordering = getattr(
RecipePlanItem.objects.filter(recipe_plan_id=plan_id).last(), "ordering", 1
)

recipes = find_recipes_applicable_for_plan(plan_id=plan_id)

normal_recipes = []
pescatarian_recipes = []
vegetarian_recipes = []

for recipe in recipes:
if recipe.is_vegetarian:
vegetarian_recipes.append(recipe)
elif recipe.is_pescatarian:
pescatarian_recipes.append(recipe)
else:
normal_recipes.append(recipe)

for recipe in recipes:
plan_items_to_create.append(
RecipePlanItem(
Expand All @@ -88,6 +100,4 @@ def _create_recipe_plan_items(plan_id: int) -> None:

ordering += 1

# TODO: assert ordering unique

RecipePlanItem.objects.bulk_create(plan_items_to_create)
2 changes: 2 additions & 0 deletions tests/recipes/test_plans_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def test_plan_distributor_create_plan():
assert False
2 changes: 2 additions & 0 deletions tests/recipes/test_plans_selectors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def test_selector_find_recipes_applicable_for_plan():
assert False
10 changes: 10 additions & 0 deletions tests/recipes/test_plans_services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def test_service_create_weekly_recipe_plan_for_home():
assert False


def test_service_create_recipe_plan(immediate_on_commit):
assert False


def test_service__create_recipe_plan_items():
assert False

0 comments on commit 7e575f4

Please sign in to comment.