From 5e180f48d559bd8a00b807567095fe8b0a1bdbea Mon Sep 17 00:00:00 2001 From: tanshu Date: Thu, 12 Nov 2020 12:32:16 +0530 Subject: [PATCH] Update Product Prices built --- barker/barker/main.py | 2 + barker/barker/printing/bill.py | 2 +- barker/barker/printing/kot.py | 4 +- barker/barker/routers/__init__.py | 5 + barker/barker/routers/modifier_category.py | 4 +- barker/barker/routers/product.py | 12 +- .../reports/beer_consumption_report.py | 2 +- .../barker/routers/reports/discount_report.py | 2 +- .../routers/reports/product_sale_report.py | 2 +- barker/barker/routers/reports/sale_report.py | 2 +- .../barker/routers/update_product_prices.py | 171 ++++++++++++++++++ barker/barker/routers/voucher/save.py | 2 +- barker/barker/routers/voucher/show.py | 2 +- barker/barker/routers/voucher/update.py | 2 +- .../barker/schemas/update_product_prices.py | 35 ++++ bookie/src/app/app-routing.module.ts | 10 +- bookie/src/app/home/home.component.html | 9 + .../product-list/product-list.component.html | 8 +- .../update-product-prices-datasource.ts | 16 ++ .../update-product-prices-item.ts | 6 + ...te-product-prices-resolver.service.spec.ts | 18 ++ .../update-product-prices-resolver.service.ts | 20 ++ ...date-product-prices-routing.module.spec.ts | 13 ++ .../update-product-prices-routing.module.ts | 45 +++++ .../update-product-prices.component.css | 9 + .../update-product-prices.component.html | 70 +++++++ .../update-product-prices.component.spec.ts | 24 +++ .../update-product-prices.component.ts | 126 +++++++++++++ .../update-product-prices.module.spec.ts | 13 ++ .../update-product-prices.module.ts | 67 +++++++ .../update-product-prices.service.spec.ts | 18 ++ .../update-product-prices.service.ts | 44 +++++ .../update-product-prices.ts | 7 + 33 files changed, 750 insertions(+), 22 deletions(-) create mode 100644 barker/barker/routers/update_product_prices.py create mode 100644 barker/barker/schemas/update_product_prices.py create mode 100644 bookie/src/app/update-product-prices/update-product-prices-datasource.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices-item.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices-resolver.service.spec.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices-resolver.service.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices-routing.module.spec.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices-routing.module.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.component.css create mode 100644 bookie/src/app/update-product-prices/update-product-prices.component.html create mode 100644 bookie/src/app/update-product-prices/update-product-prices.component.spec.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.component.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.module.spec.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.module.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.service.spec.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.service.ts create mode 100644 bookie/src/app/update-product-prices/update-product-prices.ts diff --git a/barker/barker/main.py b/barker/barker/main.py index 92c1b8d..2897738 100644 --- a/barker/barker/main.py +++ b/barker/barker/main.py @@ -21,6 +21,7 @@ from .routers import ( section_printer, table, tax, + update_product_prices, ) from .routers.auth import role, user from .routers.reports import ( @@ -67,6 +68,7 @@ app.include_router(device.router, prefix="/api/devices", tags=["devices"]) app.include_router(sale_category.router, prefix="/api/sale-categories", tags=["products"]) app.include_router(header_footer.router, prefix="/api/header-footer", tags=["products"]) app.include_router(product_updates_report.router, prefix="/api/product-updates-report", tags=["products"]) +app.include_router(update_product_prices.router, prefix="/api/update-product-prices", tags=["products"]) app.include_router(section.router, prefix="/api/sections", tags=["sections"]) app.include_router(section_printer.router, prefix="/api/section-printers", tags=["section-printers"]) diff --git a/barker/barker/printing/bill.py b/barker/barker/printing/bill.py index fbfeb47..43d53f0 100644 --- a/barker/barker/printing/bill.py +++ b/barker/barker/printing/bill.py @@ -91,7 +91,7 @@ def design_bill( <= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), diff --git a/barker/barker/printing/kot.py b/barker/barker/printing/kot.py index cd9a316..3c78498 100644 --- a/barker/barker/printing/kot.py +++ b/barker/barker/printing/kot.py @@ -44,7 +44,7 @@ def design_kot(voucher: Voucher, kot: Kot, items: List[Inventory], copy_number: <= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), @@ -76,7 +76,7 @@ def print_kot(voucher_id: uuid.UUID, db: Session): <= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= (voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date(), ), diff --git a/barker/barker/routers/__init__.py b/barker/barker/routers/__init__.py index e69de29..2a4f24b 100644 --- a/barker/barker/routers/__init__.py +++ b/barker/barker/routers/__init__.py @@ -0,0 +1,5 @@ +from datetime import date, datetime + + +def query_date(d: str = None) -> date: + return date.today() if d is None else datetime.strptime(d, "%d-%b-%Y").date() diff --git a/barker/barker/routers/modifier_category.py b/barker/barker/routers/modifier_category.py index 77b3f9b..2c4e46f 100644 --- a/barker/barker/routers/modifier_category.py +++ b/barker/barker/routers/modifier_category.py @@ -139,7 +139,7 @@ def show_list( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -223,7 +223,7 @@ def modifier_category_info(item: Optional[ModifierCategory], date_: date, db: Se ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) diff --git a/barker/barker/routers/product.py b/barker/barker/routers/product.py index 36a4865..67c35de 100644 --- a/barker/barker/routers/product.py +++ b/barker/barker/routers/product.py @@ -60,7 +60,7 @@ def sort_order( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -136,7 +136,7 @@ def update( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -209,7 +209,7 @@ def delete( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -269,7 +269,7 @@ def product_list(date_: date, db: Session) -> List[schemas.Product]: ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -308,7 +308,7 @@ async def show_term( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) @@ -347,7 +347,7 @@ def show_id( ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) diff --git a/barker/barker/routers/reports/beer_consumption_report.py b/barker/barker/routers/reports/beer_consumption_report.py index e2cba42..787531f 100644 --- a/barker/barker/routers/reports/beer_consumption_report.py +++ b/barker/barker/routers/reports/beer_consumption_report.py @@ -53,7 +53,7 @@ def beer_consumption( ProductVersion.valid_from <= day, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= day, ), Voucher.voucher_type.in_( diff --git a/barker/barker/routers/reports/discount_report.py b/barker/barker/routers/reports/discount_report.py index 071827b..02338fb 100644 --- a/barker/barker/routers/reports/discount_report.py +++ b/barker/barker/routers/reports/discount_report.py @@ -69,7 +69,7 @@ def get_discount_report(s: date, f: date, db: Session) -> List[DiscountReportIte ProductVersion.valid_from <= day, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= day, ), Voucher.voucher_type.in_([VoucherType.REGULAR_BILL.value, VoucherType.KOT.value]), diff --git a/barker/barker/routers/reports/product_sale_report.py b/barker/barker/routers/reports/product_sale_report.py index bb16111..a9382c7 100644 --- a/barker/barker/routers/reports/product_sale_report.py +++ b/barker/barker/routers/reports/product_sale_report.py @@ -79,7 +79,7 @@ def product_sale_report(s: date, f: date, db: Session): ProductVersion.valid_from <= day, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= day, ), ) diff --git a/barker/barker/routers/reports/sale_report.py b/barker/barker/routers/reports/sale_report.py index 49c82ff..f877036 100644 --- a/barker/barker/routers/reports/sale_report.py +++ b/barker/barker/routers/reports/sale_report.py @@ -86,7 +86,7 @@ def get_sale(s: date, f: date, db: Session) -> List[SaleReportItem]: ProductVersion.valid_from <= day, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= day, ), ) diff --git a/barker/barker/routers/update_product_prices.py b/barker/barker/routers/update_product_prices.py new file mode 100644 index 0000000..6819924 --- /dev/null +++ b/barker/barker/routers/update_product_prices.py @@ -0,0 +1,171 @@ +import uuid + +from datetime import date, timedelta +from decimal import Decimal +from typing import List, Optional + +from fastapi import APIRouter, Depends, HTTPException, Security, status +from sqlalchemy import and_, or_ +from sqlalchemy.orm import Session, contains_eager, joinedload + +from ..core.security import get_current_active_user as get_user +from ..db.session import SessionLocal +from ..models import MenuCategory, ProductVersion +from ..schemas.auth import UserToken +from ..schemas.update_product_prices import UpdateProductPrices, UpdateProductPricesItem +from . import query_date + + +router = APIRouter() + + +# Dependency +def get_db() -> Session: + try: + db = SessionLocal() + yield db + finally: + db.close() + + +@router.get("", response_model=UpdateProductPrices) +def get_update_product_prices( + date_: date = Depends(query_date), + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["products"]), +) -> UpdateProductPrices: + return UpdateProductPrices( + date=date_, + items=update_product_prices_list(None, date_, db), + ) + + +@router.get("/{id_}", response_model=UpdateProductPrices) +def get_update_product_prices_id( + id_: uuid.UUID, + date_: date = Depends(query_date), + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["products"]), +) -> UpdateProductPrices: + return UpdateProductPrices( + date=date_, + menuCategoryId=id_, + items=update_product_prices_list(id_, date_, db), + ) + + +def update_product_prices_list( + menu_category_id: Optional[uuid.UUID], date_: date, db: Session +) -> List[UpdateProductPricesItem]: + list_: List[ProductVersion] = ( + db.query(ProductVersion) + .join(ProductVersion.menu_category) + .filter( + and_( + 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_.filter(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( + joinedload(ProductVersion.menu_category, innerjoin=True), + contains_eager(ProductVersion.menu_category), + ).all() + + return [ + UpdateProductPricesItem(id=item.product_id, name=item.full_name, oldPrice=item.price, newPrice=item.price) + for item in list_ + ] + + +@router.post("", response_model=UpdateProductPrices) +def save_update_product_prices( + data: UpdateProductPrices, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["products"]), +) -> UpdateProductPrices: + for item in data.items: + update_product(item.id, item.new_price, data.date_, db) + db.commit() + return UpdateProductPrices( + date=data.date_, + items=update_product_prices_list(None, data.date_, db), + ) + + +@router.post("/{id_}", response_model=UpdateProductPrices) +def save_update_product_prices_id( + id_: uuid.UUID, + data: UpdateProductPrices, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["products"]), +) -> UpdateProductPrices: + for item in data.items: + update_product(item.id, item.new_price, data.date_, db) + db.commit() + return UpdateProductPrices( + date=data.date_, + menuCategoryId=id_, + items=update_product_prices_list(id_, data.date_, db), + ) + + +def update_product(id_: uuid.UUID, price: Decimal, date_: date, db: Session): + item: ProductVersion = ( + db.query(ProductVersion) + .join(ProductVersion.menu_category) + .filter( + 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_, + ), + ) + ) + .first() + ) + if item.valid_till is not None: + # Allow adding a product here splitting the valid from and to, but not implemented right now + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Product 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) diff --git a/barker/barker/routers/voucher/save.py b/barker/barker/routers/voucher/save.py index fef82d4..00a352a 100644 --- a/barker/barker/routers/voucher/save.py +++ b/barker/barker/routers/voucher/save.py @@ -126,7 +126,7 @@ def do_save( ProductVersion.valid_from <= product_date, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= product_date, ), ) diff --git a/barker/barker/routers/voucher/show.py b/barker/barker/routers/voucher/show.py index 4ddca0c..89c0179 100644 --- a/barker/barker/routers/voucher/show.py +++ b/barker/barker/routers/voucher/show.py @@ -114,7 +114,7 @@ def voucher_product(product_id: uuid.UUID, date_: date, db: Session): ProductVersion.valid_from <= date_, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= date_, ), ) diff --git a/barker/barker/routers/voucher/update.py b/barker/barker/routers/voucher/update.py index 791c760..eadcec6 100644 --- a/barker/barker/routers/voucher/update.py +++ b/barker/barker/routers/voucher/update.py @@ -106,7 +106,7 @@ def update( ProductVersion.valid_from <= product_date, ), or_( - ProductVersion.valid_till == None, # noqa: FE711 + ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= product_date, ), ) diff --git a/barker/barker/schemas/update_product_prices.py b/barker/barker/schemas/update_product_prices.py new file mode 100644 index 0000000..b8315c1 --- /dev/null +++ b/barker/barker/schemas/update_product_prices.py @@ -0,0 +1,35 @@ +import uuid + +from datetime import date, datetime +from decimal import Decimal +from typing import List, Optional + +from pydantic import BaseModel, validator + +from . import to_camel + + +class UpdateProductPricesItem(BaseModel): + id: uuid.UUID + name: str + old_price: Decimal + new_price: Decimal + + class Config: + alias_generator = to_camel + + +class UpdateProductPrices(BaseModel): + date_: date + menu_category_id: Optional[uuid.UUID] + items: List[UpdateProductPricesItem] + + class Config: + alias_generator = to_camel + json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} + + @validator("date_", pre=True) + def parse_date(cls, value): + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() diff --git a/bookie/src/app/app-routing.module.ts b/bookie/src/app/app-routing.module.ts index 5f55546..76aaa92 100644 --- a/bookie/src/app/app-routing.module.ts +++ b/bookie/src/app/app-routing.module.ts @@ -40,7 +40,8 @@ const routes: Routes = [ }, { path: 'header-footer', - loadChildren: () => import('./header-footer/header-footer.module').then((mod) => mod.HeaderFooterModule), + loadChildren: () => + import('./header-footer/header-footer.module').then((mod) => mod.HeaderFooterModule), }, { path: 'modifiers', @@ -119,6 +120,13 @@ const routes: Routes = [ path: 'tax-report', loadChildren: () => import('./tax-report/tax-report.module').then((mod) => mod.TaxReportModule), }, + { + path: 'update-product-prices', + loadChildren: () => + import('./update-product-prices/update-product-prices.module').then( + (mod) => mod.UpdateProductPricesModule, + ), + }, { path: 'users', loadChildren: () => import('./users/users.module').then((mod) => mod.UsersModule), diff --git a/bookie/src/app/home/home.component.html b/bookie/src/app/home/home.component.html index 4f24d42..1ea648b 100644 --- a/bookie/src/app/home/home.component.html +++ b/bookie/src/app/home/home.component.html @@ -215,6 +215,15 @@ >

Product Updates Report

+ +

Update Product Prices

+