46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
import datetime
|
|
|
|
from sqlalchemy import Date, ForeignKey, Integer, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from fooder.domain.base import Base, CommonMixin
|
|
from fooder.domain.meal import Meal
|
|
|
|
|
|
class Diary(Base, CommonMixin):
|
|
"""Diary represents user diary for given day."""
|
|
|
|
__table_args__ = (UniqueConstraint("user_id", "date"),)
|
|
|
|
meals: Mapped[list[Meal]] = relationship(
|
|
lazy="selectin", order_by=Meal.order.desc()
|
|
)
|
|
date: Mapped[datetime.date] = mapped_column(Date)
|
|
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("user.id"))
|
|
# snapshot of user settings at diary creation time — intentionally decoupled
|
|
# from UserSettings so historical goals don't change when settings are updated
|
|
protein_goal: Mapped[float]
|
|
carb_goal: Mapped[float]
|
|
fat_goal: Mapped[float]
|
|
fiber_goal: Mapped[float]
|
|
calories_goal: Mapped[float]
|
|
|
|
@property
|
|
def calories(self) -> float:
|
|
return sum(meal.calories for meal in self.meals)
|
|
|
|
@property
|
|
def protein(self) -> float:
|
|
return sum(meal.protein for meal in self.meals)
|
|
|
|
@property
|
|
def carb(self) -> float:
|
|
return sum(meal.carb for meal in self.meals)
|
|
|
|
@property
|
|
def fat(self) -> float:
|
|
return sum(meal.fat for meal in self.meals)
|
|
|
|
@property
|
|
def fiber(self) -> float:
|
|
return sum(meal.fiber for meal in self.meals)
|