diff --git a/brewman/brewman/routers/attendance.py b/brewman/brewman/routers/attendance.py index 1f3152a8..4dd4edea 100644 --- a/brewman/brewman/routers/attendance.py +++ b/brewman/brewman/routers/attendance.py @@ -119,7 +119,7 @@ def save( def date_range( start: date, stop: date, step: timedelta = timedelta(days=1), inclusive: bool = False -) -> Generator[date, None, None]: +) -> Generator[date]: # inclusive=False to behave like range by default if step.days > 0: while start < stop: diff --git a/brewman/brewman/routers/recipe.py b/brewman/brewman/routers/recipe.py index 48745eb1..e689a6b7 100644 --- a/brewman/brewman/routers/recipe.py +++ b/brewman/brewman/routers/recipe.py @@ -125,7 +125,9 @@ async def update_route( item.quantity = round(new_item.quantity, 2) item.description = new_item.description else: + db.delete(item) recipe.items.remove(item) + db.flush() for d_item in data.items: product = db.execute(select(Product).where(Product.id == d_item.product.id_)).scalar_one() @@ -152,9 +154,16 @@ def check_recursion(product: uuid.UUID, visited: set[uuid.UUID], db: Session) -> detail="Recipe recursion. Some ingredient recipe contains parent recipe.", ) recipe = ( - db.execute(select(Recipe).join(Recipe.items).join(Recipe.sku).where(StockKeepingUnit.product_id == product)) + db.execute( + select(Recipe) + .join(Recipe.items) + .join(Recipe.sku) + .options(contains_eager(Recipe.items)) + .where(StockKeepingUnit.product_id == product) + ) .unique() - .scalar_one_or_none() + .scalars() + .first() ) if recipe is None: return @@ -239,14 +248,15 @@ async def show_list( .join(ProductVersion, onclause=product_version_onclause) .join(ProductVersion.product_group) .options( + contains_eager(Recipe.sku).contains_eager(StockKeepingUnit.versions), contains_eager(Recipe.sku) - .contains_eager(StockKeepingUnit.versions) .contains_eager(StockKeepingUnit.product) .contains_eager(Product.versions) - .contains_eager(ProductVersion.product_group) + .contains_eager(ProductVersion.product_group), ) .order_by(ProductVersion.name) ) + .unique() .scalars() .all() ) @@ -302,15 +312,15 @@ def show_pdf( @router.get("/xlsx", response_class=StreamingResponse) def get_report( p: uuid.UUID, - t: uuid.UUID | None = None, + pg: uuid.UUID | None = None, ) -> StreamingResponse: with SessionFuture() as db: - calculate_prices(t, db) + calculate_prices(p, db) db.commit() prices: list[tuple[str, str, Decimal]] = [] with SessionFuture() as db: pq = ( - db.execute(select(Price).where(Price.period_id == t).options(joinedload(Price.product, innerjoin=True))) + db.execute(select(Price).where(Price.period_id == p).options(joinedload(Price.product, innerjoin=True))) .unique() .scalars() .all() @@ -318,6 +328,7 @@ def get_report( prices = [(i.product.versions[-1].name, i.product.versions[-1].fraction_units, i.price) for i in pq] list_: Sequence[Recipe] = [] + print("test2") with SessionFuture() as db: RecipeProductVersion = aliased(ProductVersion, name="recipe_product_version") ItemProductVersion = aliased(ProductVersion, name="item_product_version") @@ -384,8 +395,8 @@ def get_report( contains_eager(Recipe.sku).contains_eager(StockKeepingUnit.versions, alias=CurrentSkuVersion), ) ) - if p is not None: - q = q.where(RecipeProductVersion.product_group_id == p) + if pg is not None: + q = q.where(RecipeProductVersion.product_group_id == pg) list_ = db.execute(q).unique().scalars().all() e = excel(prices, sorted(list_, key=lambda r: r.sku.product.versions[0].name)) e.seek(0) @@ -569,7 +580,8 @@ def recipe_info(recipe: Recipe) -> schemas.Recipe: id_=item.id, product=schemas.ProductLink( id_=item.product.id, - name=f"{item.product.versions[0].name} ({item.product.versions[0].fraction_units})", + name=item.product.versions[0].name, + fraction_units=item.product.versions[0].fraction_units, ), quantity=round(item.quantity, 2), description=item.description, diff --git a/brewman/brewman/schemas/product.py b/brewman/brewman/schemas/product.py index bbc7c2f2..ec1f5a55 100644 --- a/brewman/brewman/schemas/product.py +++ b/brewman/brewman/schemas/product.py @@ -12,6 +12,7 @@ from .stock_keeping_unit import StockKeepingUnit class ProductLink(BaseModel): id_: uuid.UUID = Field(...) name: str | None = None + fraction_units: str | None = None model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/overlord/src/app/product/product-detail/product-detail.component.css b/overlord/src/app/product/product-detail/product-detail.component.css index e69de29b..d4041d9d 100644 --- a/overlord/src/app/product/product-detail/product-detail.component.css +++ b/overlord/src/app/product/product-detail/product-detail.component.css @@ -0,0 +1,11 @@ +.nutrition-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + align-items: stretch; + justify-items: stretch; +} +.nutrition-grid > * { + width: 100%; + box-sizing: border-box; /* helps with padding */ +} diff --git a/overlord/src/app/product/product-detail/product-detail.component.html b/overlord/src/app/product/product-detail/product-detail.component.html index 7679648b..ca9b92eb 100644 --- a/overlord/src/app/product/product-detail/product-detail.component.html +++ b/overlord/src/app/product/product-detail/product-detail.component.html @@ -47,7 +47,7 @@ @if (item.productGroup?.nutritional ?? false) {