From 22f888500ffb297b4bc21570d899584010ace331 Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Mon, 26 Jan 2026 14:00:14 +0000 Subject: [PATCH] Update product prices now working --- .../barker/routers/update_product_prices.py | 162 ++++++++++-------- 1 file changed, 95 insertions(+), 67 deletions(-) diff --git a/barker/barker/routers/update_product_prices.py b/barker/barker/routers/update_product_prices.py index 90d415de..29d4fd68 100644 --- a/barker/barker/routers/update_product_prices.py +++ b/barker/barker/routers/update_product_prices.py @@ -7,6 +7,11 @@ from fastapi import APIRouter, Depends, HTTPException, Security, status from sqlalchemy import and_, or_, select from sqlalchemy.orm import Session, contains_eager +from barker.models.product import Product +from barker.models.sale_category import SaleCategory +from barker.models.sku_version import SkuVersion +from barker.models.stock_keeping_unit import StockKeepingUnit + from ..core.security import get_current_active_user as get_user from ..db.session import SessionFuture from ..models.menu_category import MenuCategory @@ -59,38 +64,66 @@ def get_update_product_prices_id( def update_product_prices_list( menu_category_id: uuid.UUID | None, date_: date, db: Session ) -> list[UpdateProductPricesItem]: - list_ = ( - select(ProductVersion) - .join(ProductVersion.menu_category) - .where( - and_( - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= date_, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= date_, - ), - ) - ) + product_version_onclause = and_( + ProductVersion.product_id == Product.id, + or_( + ProductVersion.valid_from == None, # noqa: E711 + ProductVersion.valid_from <= date_, + ), + or_( + ProductVersion.valid_till == None, # noqa: E711 + ProductVersion.valid_till >= date_, + ), ) - if menu_category_id is not None: - list_ = list_.where(ProductVersion.menu_category_id == menu_category_id) - list_.order_by( - MenuCategory.sort_order, - MenuCategory.name, - ProductVersion.sort_order, - ProductVersion.name, - ProductVersion.valid_from.nullsfirst(), - ).options( - contains_eager(ProductVersion.menu_category), + sku_version_onclause = and_( + SkuVersion.sku_id == StockKeepingUnit.id, + or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= date_), # noqa: E711 + or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= date_), # noqa: E711 ) - return [ - UpdateProductPricesItem(id=item.product_id, name=item.full_name, old_price=item.price, new_price=item.price) - for item in db.execute(list_).scalars().all() - ] + stmt = ( + select(SkuVersion) + .join(SkuVersion.menu_category) + .join(StockKeepingUnit, onclause=sku_version_onclause) + .join(StockKeepingUnit.product) + .join(ProductVersion, onclause=product_version_onclause) + .join(ProductVersion.sale_category) + ) + + if menu_category_id is not None: + stmt = stmt.where(SkuVersion.menu_category_id == menu_category_id) + + stmt = stmt.order_by( + SaleCategory.name, + MenuCategory.sort_order, + MenuCategory.name, + Product.sort_order, + ProductVersion.name, + StockKeepingUnit.sort_order, + SkuVersion.units, + ).options( + contains_eager(SkuVersion.menu_category), + contains_eager(SkuVersion.sku) + .contains_eager(StockKeepingUnit.product) + .contains_eager(Product.versions) + .contains_eager(ProductVersion.sale_category), + ) + + items = db.execute(stmt).unique().scalars().all() + + # Build display name: "ProductName (units)" — similar to old full_name + out: list[UpdateProductPricesItem] = [] + for sv in items: + full_name = f"{sv.sku.product.versions[0].name} ({sv.units})" + out.append( + UpdateProductPricesItem( + id=sv.sku_id, + name=full_name, + old_price=sv.sale_price, + new_price=sv.sale_price, + ) + ) + return out @router.post("", response_model=UpdateProductPrices) @@ -100,7 +133,7 @@ def save_update_product_prices( ) -> UpdateProductPrices: with SessionFuture() as db: for item in data.items: - update_product(item.id, item.new_price, data.date_, db) + update_sku_price(item.id, item.new_price, data.date_, db) db.commit() return UpdateProductPrices( date_=data.date_, @@ -116,7 +149,7 @@ def save_update_product_prices_id( ) -> UpdateProductPrices: with SessionFuture() as db: for item in data.items: - update_product(item.id, item.new_price, data.date_, db) + update_sku_price(item.id, item.new_price, data.date_, db) db.commit() return UpdateProductPrices( date_=data.date_, @@ -125,46 +158,41 @@ def save_update_product_prices_id( ) -def update_product(id_: uuid.UUID, price: Decimal, date_: date, db: Session) -> None: - raise NotImplementedError - item: ProductVersion = db.execute( - select(ProductVersion).where( +def update_sku_price(sku_id: uuid.UUID, sale_price: Decimal, date_: date, db: Session) -> None: + sv: SkuVersion = db.execute( + select(SkuVersion).where( and_( - ProductVersion.product_id == id_, - or_( - ProductVersion.valid_from == None, # noqa: E711 - ProductVersion.valid_from <= date_, - ), - or_( - ProductVersion.valid_till == None, # noqa: E711 - ProductVersion.valid_till >= date_, - ), + SkuVersion.sku_id == sku_id, + or_(SkuVersion.valid_from == None, SkuVersion.valid_from <= date_), # noqa: E711 + or_(SkuVersion.valid_till == None, SkuVersion.valid_till >= date_), # noqa: E711 ) ) ).scalar_one() - if item.valid_till is not None: - # Allow adding a product here splitting the valid from and to, but not implemented right now + + if sv.valid_till is not None: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="Product has been invalidated", + detail="SKU version has been invalidated", ) - if item.valid_from == date_: # Update the product as valid from the the same - item.price = price - db.commit() - else: # Create a new version of the product from the new details - item.valid_till = date_ - timedelta(days=1) - product_version = ProductVersion( - product_id=item.product_id, - name=item.name, - units=item.units, - menu_category_id=item.menu_category_id, - sale_category_id=item.sale_category_id, - price=price, - has_happy_hour=item.has_happy_hour, - is_not_available=item.is_not_available, - quantity=item.quantity, - valid_from=date_, - valid_till=None, - sort_order=item.sort_order, - ) - db.add(product_version) + + if sv.valid_from == date_: + sv.sale_price = sale_price + return + + # Close current version the day before + sv.valid_till = date_ - timedelta(days=1) + + # Create a new version cloning everything else + new_sv = SkuVersion( + sku_id=sv.sku_id, + units=sv.units, + fraction=sv.fraction, + product_yield=sv.product_yield, + cost_price=sv.cost_price, + sale_price=sale_price, + has_happy_hour=sv.has_happy_hour, + menu_category_id=sv.menu_category_id, + valid_from=date_, + valid_till=None, + ) + db.add(new_sv)