diff --git a/sigl/domain/service.py b/sigl/domain/service.py index a1854df..17a0feb 100644 --- a/sigl/domain/service.py +++ b/sigl/domain/service.py @@ -8,8 +8,56 @@ from typing import List, Optional, Union from sqlalchemy.orm import Session -from sigl.exc import NotFoundError -from .models import ListEntry, ShoppingList +from sigl.exc import DomainError, NotFoundError +from .models import ListEntry, Product, ShoppingList + + +def list_addItem( + session: Session, + id: int, + *, + productId: Optional[int], + productName: Optional[str], + productCategory: Optional[str], + quantity: Optional[str], + notes: Optional[str], +) -> ListEntry: + """Add a Product to a Shopping List. + + If the `productId` parameter is provided, the method will look up the + product by ID and add it to the list. If the `product` parameter is not + provided, a new `Product` will be created with the provided `productName` + and `productCategory` values. + """ + sList = list_by_id(session, id) + if not sList: + raise NotFoundError(f'List {id} does not exist') + + product = None + if not productId: + if not productName: + raise DomainError('Product Name cannot be empty') + + product = Product(name=productName, category=productCategory) + + session.add(product) + + else: + product = product_by_id(session, productId) + if not product: + raise NotFoundError(f'Product {productId} does not exist') + + entry = ListEntry( + shoppingList=sList, + product=product, + quantity=quantity, + notes=notes, + ) + + session.add(entry) + session.commit() + + return entry def lists_all(session: Session) -> List[ShoppingList]: @@ -43,7 +91,7 @@ def list_delete(session: Session, id: int): def list_stores(session: Session, id: int) -> List[str]: """Get a list of all Stores for the List. - + This helper returns a list of all Stores for which the Products in the List have locations. """ @@ -67,8 +115,8 @@ def list_stores(session: Session, id: int) -> List[str]: def list_update( session: Session, id: int, - name: Union[str,None], - notes: Union[str,None], + name: Union[str, None], + notes: Union[str, None], ) -> ShoppingList: """Update the Name and/or Notes of a Shopping List.""" sList = list_by_id(session, id) @@ -82,3 +130,13 @@ def list_update( session.commit() return sList + + +def products_all(session: Session) -> List[Product]: + """Return all Products.""" + return session.query(Product).all() + + +def product_by_id(session: Session, id: int) -> Optional[Product]: + """Load a specific Product.""" + return session.query(Product).filter(Product.id == id).one_or_none() diff --git a/sigl/templates/lists/detail.html.j2 b/sigl/templates/lists/detail.html.j2 index 59be874..86f26ad 100644 --- a/sigl/templates/lists/detail.html.j2 +++ b/sigl/templates/lists/detail.html.j2 @@ -4,7 +4,7 @@