From 78fccb6a940a827946d66c8364b099541b908ae1 Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 22 Nov 2024 17:59:44 +0100 Subject: [PATCH 1/4] add .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e928de1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class \ No newline at end of file From b453880cf472443bb7b821d91b00adff75a5b5ba Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 22 Nov 2024 17:42:56 +0100 Subject: [PATCH 2/4] add basic entity layer --- src/entities/cart.py | 27 +++++++++++++++++++++++++++ src/entities/cart_item.py | 17 +++++++++++++++++ src/entities/product.py | 13 +++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/entities/cart.py create mode 100644 src/entities/cart_item.py create mode 100644 src/entities/product.py diff --git a/src/entities/cart.py b/src/entities/cart.py new file mode 100644 index 0000000..b849bd7 --- /dev/null +++ b/src/entities/cart.py @@ -0,0 +1,27 @@ +#python imports +from typing import List +from dataclasses import dataclass + +#dependency imports +from entities.cart_item import CartItem +from entities.product import Product + +@dataclass +class Cart: + items: List[CartItem] + + def add_item(self, product: Product, quantity: int): + for item in self.items: + if item.product.id == product.id: + item.quantity += quantity + return + self.items.append(CartItem(product=product, quantity=quantity)) + + def remove_item(self, product_id: str): + self.items = [item for item in self.items if item.product.id != product_id] + + def calculate_total_price(self) -> float: + return sum(item.calculate_total_price() for item in self.items) + + def list_items(self) -> List[str]: + return [f"{item.quantity} x {item.product.name} - {item.calculate_total_price()} EUR" for item in self.items] \ No newline at end of file diff --git a/src/entities/cart_item.py b/src/entities/cart_item.py new file mode 100644 index 0000000..3278b03 --- /dev/null +++ b/src/entities/cart_item.py @@ -0,0 +1,17 @@ +#python imports +from typing import List +from dataclasses import dataclass + +@dataclass +class CartItem: + product_id: int + name: str + quantity: int + price: float + + def post_init(self): + if self.quantity <= 0: + raise ValueError("Quantity has to be atleast 1") + + def calculate_total_price(self) -> float: + return self.quantity * self.price \ No newline at end of file diff --git a/src/entities/product.py b/src/entities/product.py new file mode 100644 index 0000000..ae7341f --- /dev/null +++ b/src/entities/product.py @@ -0,0 +1,13 @@ +#python imports +from dataclasses import dataclass + +@dataclass +class Product: + id: str + name: str + description: str + price: float + + def post_init(self): + if self.price < 0: + raise ValueError("Der Preis darf nicht negativ sein.") \ No newline at end of file From 6b2ab755616070cdda6c59c9b9f6db14d65260ad Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 22 Nov 2024 17:46:32 +0100 Subject: [PATCH 3/4] add basic usecase layer --- src/use_cases/cart_repository_interface.py | 8 ++++++++ src/use_cases/view_cart.py | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/use_cases/cart_repository_interface.py create mode 100644 src/use_cases/view_cart.py diff --git a/src/use_cases/cart_repository_interface.py b/src/use_cases/cart_repository_interface.py new file mode 100644 index 0000000..5bf005a --- /dev/null +++ b/src/use_cases/cart_repository_interface.py @@ -0,0 +1,8 @@ +from typing import Optional, List + +class CartRepositoryInterface: + def fetch_cart_by_user_id(self, user_id: int) -> Optional[List[dict]]: + """ + Abstract method to fetch cart data by user ID. + """ + raise NotImplementedError("fetch_cart_by_user_id must be implemented by a subclass") diff --git a/src/use_cases/view_cart.py b/src/use_cases/view_cart.py new file mode 100644 index 0000000..5618362 --- /dev/null +++ b/src/use_cases/view_cart.py @@ -0,0 +1,22 @@ +#python imports +from typing import Optional + +#dependency imports +from entities.cart import Cart, CartItem +from interface_adapters.cart_repository import CartRepository + +class ViewCart: + def __init__(self, cart_repository: CartRepository): + self.cart_repository = cart_repository + + def execute(self, user_id: int) -> Optional[Cart]: + """ + Fetches the cart data from the repository, converts it to Cart entity. + """ + cart_data = self.cart_repository.fetch_cart_by_user_id(user_id) + if not cart_data: + return None + + # Convert raw data to domain entities + items = [CartItem(**item) for item in cart_data] + return Cart(items) \ No newline at end of file From 9ad635f8ec8d1f33bb7df22e4beb35537b48eaa6 Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 22 Nov 2024 17:48:52 +0100 Subject: [PATCH 4/4] add interface adapters for db --- src/interface_adapters/cart_database_interface.py | 8 ++++++++ src/interface_adapters/cart_repository.py | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/interface_adapters/cart_database_interface.py create mode 100644 src/interface_adapters/cart_repository.py diff --git a/src/interface_adapters/cart_database_interface.py b/src/interface_adapters/cart_database_interface.py new file mode 100644 index 0000000..1c9964f --- /dev/null +++ b/src/interface_adapters/cart_database_interface.py @@ -0,0 +1,8 @@ +from typing import Optional, List + +class CartDatabaseInterface: + def fetch_cart_items(self, user_id: int) -> Optional[List[dict]]: + """ + Abstract method to fetch cart items from the database for a given user ID. + """ + raise NotImplementedError("fetch_cart_items must be implemented by a subclass") \ No newline at end of file diff --git a/src/interface_adapters/cart_repository.py b/src/interface_adapters/cart_repository.py new file mode 100644 index 0000000..25663b6 --- /dev/null +++ b/src/interface_adapters/cart_repository.py @@ -0,0 +1,13 @@ +#python imports +from typing import Optional, List + +#dependency imports +from use_cases.cart_repository_interface import CartRepositoryInterface +from interface_adapters.cart_database_interface import CartDatabaseInterface + +class CartRepository(CartRepositoryInterface): + def __init__(self, database_gateway: CartDatabaseInterface): + self.database_gateway = database_gateway + + def fetch_cart_by_user_id(self, user_id: int) -> Optional[List[dict]]: + return self.database_gateway.fetch_cart_items(user_id) \ No newline at end of file