Coverage for opt/mealie/lib/python3.12/site-packages/mealie/schema/meal_plan/new_meal.py: 100%

51 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 03:04 +0000

1from datetime import date 

2from enum import Enum 

3from typing import Annotated 

4from uuid import UUID 

5 

6from pydantic import ConfigDict, Field, field_validator 

7from pydantic_core.core_schema import ValidationInfo 

8from sqlalchemy.orm import selectinload 

9from sqlalchemy.orm.interfaces import LoaderOption 

10 

11from mealie.db.models.household import GroupMealPlan 

12from mealie.db.models.recipe import RecipeModel 

13from mealie.db.models.users.users import User 

14from mealie.schema._mealie import MealieModel 

15from mealie.schema.recipe.recipe import RecipeSummary 

16from mealie.schema.response.pagination import PaginationBase 

17 

18 

19class PlanEntryType(str, Enum): 

20 breakfast = "breakfast" 

21 lunch = "lunch" 

22 dinner = "dinner" 

23 side = "side" 

24 

25 

26class CreateRandomEntry(MealieModel): 

27 date: date 

28 entry_type: PlanEntryType = PlanEntryType.dinner 

29 

30 

31class CreatePlanEntry(MealieModel): 

32 date: date 

33 entry_type: PlanEntryType = PlanEntryType.breakfast 

34 title: str = "" 

35 text: str = "" 

36 recipe_id: Annotated[UUID | None, Field(validate_default=True)] = None 

37 

38 @field_validator("recipe_id") 

39 @classmethod 

40 def id_or_title(cls, value, info: ValidationInfo): 

41 if bool(value) is False and bool(info.data["title"]) is False: 

42 raise ValueError(f"`recipe_id={value}` or `title={info.data['title']}` must be provided") 

43 

44 return value 

45 

46 

47class UpdatePlanEntry(CreatePlanEntry): 

48 id: int 

49 group_id: UUID 

50 user_id: UUID 

51 

52 

53class SavePlanEntry(CreatePlanEntry): 

54 group_id: UUID 

55 user_id: UUID 

56 model_config = ConfigDict(from_attributes=True) 

57 

58 

59class ReadPlanEntry(UpdatePlanEntry): 

60 household_id: UUID 

61 recipe: RecipeSummary | None = None 

62 model_config = ConfigDict(from_attributes=True) 

63 

64 @classmethod 

65 def loader_options(cls) -> list[LoaderOption]: 

66 return [ 

67 selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.recipe_category), 

68 selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.tags), 

69 selectinload(GroupMealPlan.recipe).joinedload(RecipeModel.tools), 

70 selectinload(GroupMealPlan.user).load_only(User.household_id), 

71 ] 

72 

73 

74class PlanEntryPagination(PaginationBase): 

75 items: list[ReadPlanEntry]