fooder-api/fooder/controller/product.py

74 lines
2.2 KiB
Python

from fooder.controller.base import ModelController
from fooder.domain import Product
from fooder.context import Context
from fooder.exc import NotFound, InvalidValue
from fooder.model.product import ProductCreateModel, ProductUpdateModel
from fooder.utils import product_finder
from fooder.utils.calories import calculate_calories
class ProductController(ModelController[Product]):
@classmethod
async def create(
cls,
ctx: Context,
data: ProductCreateModel,
) -> "ProductController":
obj = Product(
name=data.name,
protein=data.protein,
carb=data.carb,
fat=data.fat,
fiber=data.fiber,
calories=data.resolved_calories,
barcode=data.barcode,
)
await ctx.repo.product.create(obj)
return cls(ctx, obj)
async def update(self, data: ProductUpdateModel) -> None:
if data.name is not None:
self.obj.name = data.name
if data.protein is not None:
self.obj.protein = data.protein
if data.carb is not None:
self.obj.carb = data.carb
if data.fat is not None:
self.obj.fat = data.fat
if data.fiber is not None:
self.obj.fiber = data.fiber
if data.barcode is not None:
self.obj.barcode = data.barcode
self.obj.calories = data.calories if data.calories is not None else calculate_calories(
protein=self.obj.protein,
carb=self.obj.carb,
fat=self.obj.fat,
fiber=self.obj.fiber,
)
await self.ctx.repo.product.update(self.obj)
@classmethod
async def import_by_barcode(cls, ctx: Context, barcode: str) -> "ProductController":
try:
found = await product_finder.find(barcode)
except product_finder.NotFound:
raise NotFound()
except product_finder.ParseError:
raise InvalidValue()
return await cls.create(ctx, ProductCreateModel(
name=found.name,
calories=found.kcal,
fat=found.fat,
protein=found.protein,
carb=found.carb,
fiber=found.fiber,
barcode=barcode,
))